You need to sign in to do that
Don't have an account?
msimonds
How to access APEX classes
I am new to APEX classes and have a few questions. I posted once in the PHP forums to try and find a solution, but the answers were not clear
1) If I create an APEX class can I access this from an external server/system or set of scripts that I write? The script can be written in any language: PHP, Perl, etc....
2) Once I create the class and generate the WSDL from the class, do I download it and then use this like I do the Partner WSDL file
Any help or guidance would be appreciated.
I hope this is not too generic to answer my questions
Thanks,
Mike
1) If I create an APEX class can I access this from an external server/system or set of scripts that I write? The script can be written in any language: PHP, Perl, etc....
2) Once I create the class and generate the WSDL from the class, do I download it and then use this like I do the Partner WSDL file
Any help or guidance would be appreciated.
I hope this is not too generic to answer my questions
Thanks,
Mike
I will give that a try, I appreciate the guidance
~Mike
Another developer we're working with has developed some Apex classes as webServices. I've downloaded the php toolkit and the wsdl, and tried to access a simple method called "subscribe", which gave me a "INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session" error.
Looking about a bit I discovered it was necessary to get a session id first, which I am able to do via the partner wsdl and the "login" method. I then tried setting the sessionId for a new connection via a setSessionHeader call, but when I try and call the "subscribe" method again, I get the same invalid session error.
I am posting a bit of code to illustrate what I'm referring to below.
Any tips, pointers or help would be greatly appreciated... thanks!
In trying to use a generic PHP5 SoapClient instead of a SforcePartner client, I'm no longer getting the "Invalid Session ID" message, and am now getting an "Element {}item invalid at this location" error.
It occurs to me that this could be because I'm not even getting to the point where the session id can be judged invalid, however with such a non-specific error message it's hard for me to tell at this point.
I've also tried the lower level SoapCall function, which returns the same error unfortunately
As always, any tips, pointers, etc. are appreciated!
And I'm back to "INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session"
You can get the correct namespace from your integration.wsdl (look at the targetNamespace attribute of the schema element)
First off thanks for the help!
I tried what you suggested, as shown below...
...however, I'm still getting the INVALID_SESSION_ID error. Any other ideas on what might be causing it?
Thanks again!
Clint
As a result of multiple changes to my code I was using $loginResult->sessionId instead of $mylogin->sessionId, which was, of course, null.
Once I set it to the correct value with the new namespace it worked straight off.
Thanks again Simon, you're a prince among developers! :smileyhappy:
Can you post an example? That would be EXTREMELY helpful, if you do not mind, I would truly appreciate it
~Mike
Well, the Apex class method I'm connecting to appears to be a stub at the moment, so it's hard to tell if I'm calling it 100% correctly. I'm not developing the Salesforce end of it, my responsibility at this point is to push subscriber data in. But at this point yes, I am able to connect via the partner wsdl and call the method via SOAP without raising an error.
The relevant portions of the Apex code seem to be:
My php test code looks as follows:
So what I'm doing is basically connecting to the partner wsdl via the SforcePartnerClient and logging in via the login method, which returns, among other things, a session id.
I then instantiate a php SoapClient and SoapHeader. The key part of solving the problem that I was having (thanks again, Simon!) was to set the namespace of the SoapHeader to the value specified by the targetNamespace attribute of the xsd:schema node. Then just set the name of the SoapHeader to "SessionHeader" with a value of an array with the name/value pair of "sessionId"/$mylogin->sessionId (or the "sessionId" portion of the value returned from the partner wsdl login call).
There may be further bumps in the road here as the subscribe function is fleshed out, of course (as I mentioned, I'm very new to Salesforce), but for now I can connect and call the function with no errors raised.
Clint
Listen this may sound stupid and forgive me for that
Can you try and explain what you are doing calling the Service? I have done a lot of integration with Salesforce using PHP, but never really figured out what would be a good reason to use PHP to connect to an APEX class?
I am just trying to get some ideas
~Mike
Well, in our case we've been working with an existing client for years and have developed a website for them that contains newsletter subscriptions, speaking and consulting requests, targeted mini-sites withing the main sites for certain groups that collect various bits of information, and a store.
A couple of months ago they decided they wanted to transition to a centralized place to aggregate all this information and after a bit of research they ultimately went with salesforce.
In the case of the subscribe method detailed above, we're basically creating a contact in salesforce when someone signs up for their newsletter.
Next up we'll be pushing in data from various points in the store: when a purchase is made, when a purchase order is initially entered and later when it's approved or denied, when a customer adds an address, changes an existing address, etc.
That's pretty much the scope of what we're doing so far :smileyhappy:
Clint
So basically it seems to me that you are just capturing data and inserting it into salesforce as a contact via this web service? Hmmmm sounds interesting
So your script is handing off this data to another APEX process, I like it
BUT I am not sure I would use a web service for this or even deem it necessary. Why not just create a contact straight in to Salesforce without using an APEX class
Is it faster to do it this way?
I guess that is where I am confused, but your example has really opened the door for me to try new things, and again, thanks for the example
The reason for using a web service probably started initially with the store. There's a lot going on there code-wise, so I think the decision was taken at some point that putting in a quick webservice call in the middle of the existing code in order to have the data pushed to salesforce.
Same with the newsletter. We're populating an existing suite that we use for mass mailings with the data, so I think it made sense to just insert a quick webservice call.
Ultimately though, I'm merely the implementer here, as our client hired a salesforce guy, so from my end it was "here's the wsdl, now make it go!"
Clint
~Mike
Hi. I just wanted to relate my experience on this topic, as it took me quite awhile to get this working right for even the most simple web service method. I had the following Apex web service method:
Not exactly complicated. I wanted to call this from a PHP script using PHP 5.
Alas, this did not work. It seems like the string "Hey you" was not being passed properly. After much searching and experimenting I found some tips and figured out that I have to invoke the web service method as follows (the following three lines replace the $client->greetUser("Hey you") call above):
I'm getting a session id from the login call without any problem. The namespace is straight out of the generated WSDL file. The only thing I can see that might be different is that my Apex class is managed - could that be causing the error?
Maybe I am a little lost when it comes to "why would you want to access an APEX class from PHP"
I know that you were just running a test, but are you greeting the user in an application on your server? Or in Salesforce?
What was the purpose of the test. Why would you want to be able to access the Class
I am just understanding why you would want to do this, just trying to get a clearer picture on why it would be important since APEX is really used within Salesforce for performing needs within your instance
Sorry for sounding stupid, just trying to see if I could somehow use this within our applications
Thanks,
Mike
and used the following php (just like yours)
Again, why wouldn't you just use a SOQL statement to get the same information?
Sorry to make this thread bleed even more!
~Mike
Message Edited by msimonds on 08-19-2008 09:13 AM
TLF wrote:
My requirement, ultimately, is to be able to create an object in Salesforce, from a PHP web application. I wanted to be able to perform some custom business logic first (implemented in the server-side APEX method), before the object is created. Basically, I'm trying to do something similar to web-to-lead functionality, but web-to-lead didn't quite suit my needs. Hope this helps.
That makes some sense to me and thank you for replying to my post.
So all your business logic/checks will be handled in the APEX class by passing it the web to lead information via the API
I get it and that does make it a little more clearer
~Mike
1. encapsulate data requests that would otherwise require multiple queries or roundtrips. for distributed computing round trips are evil, if you have an integration where you need multiple pieces of data, and/or you need to perform additional computation on that data, you can write this in apex and expose it as a web service so that your integration only needs to make one round trip. (this is particularly useful if for example you need to query 100 rows to calculate 2 or 3 values, you can do the calculation near the data, and just ship the small results over the WAN).
2. control transaction boundaries. the enterprise or partner APIs only allow you to insert/update data of a single type in a single transaction, this makes integrations into more complex data models much more complex, for example if you're trying to integrate opportunities, then you might want to create opportunities, line items, contact roles etc all in a single transaction to make error recovery much simpler. In the regular API, this requires you to build compensating actions for failures (e.g. insert opportunity, insert line items, insert contact roles, if the last fails, you may need to go back and delete the opportunity). By moving these multi-type inserts into apex, you can create these complex object hierarchies in a single transaction, and simplify your integrations error handling.
SimonF wrote:
There's 2 main reasons to use apex web services.
1. encapsulate data requests that would otherwise require multiple queries or roundtrips. for distributed computing round trips are evil, if you have an integration where you need multiple pieces of data, and/or you need to perform additional computation on that data, you can write this in apex and expose it as a web service so that your integration only needs to make one round trip. (this is particularly useful if for example you need to query 100 rows to calculate 2 or 3 values, you can do the calculation near the data, and just ship the small results over the WAN).
Thanks for the clarification Simon, I do appreciate it
So we have this process currently using PHP to create a new record in a custom object.
1) a work flow kicks off am outbound message with 10 fields on the SOAP message when a status is changed to "Won"
2) We take that inbound message from Salesforce and process it, we query 4 standard objects to get data we need via the API
3) we use this data to create a new record on the new custom object
In this case, we could build this right into Salesforce using APEX, am I correct?
If this is the case, we would not need to access a web service via the API, am I correct?
Our process works perfectly, but I was looking into using APEX for future items such as this.
I appreciate your help
~Mike
For anyone else who might be struggling with this error, I did have to remove the cached wsdl file from my server. Often this is stored in your /tmp directory.
Thanks for the suggestion!
Ron Wild wrote:
Updating the Partner WSDL did the trick ... apparently I had overwritten the current version when I upgraded to the latest PHP toolkit.
For anyone else who might be struggling with this error, I did have to remove the cached wsdl file from my server. Often this is stored in your /tmp directory.
Thanks for the suggestion!
Ron
At the top of all my scripts integrating with Salesforce I place the following code:
that way I do not have any cache problems
~Mike
PS: Thanks Simon I appreciate it!
Message Edited by msimonds on 08-19-2008 11:15 AM
Using your example, I have it working where I can call the Web Service as along as I don't pass any parameters in. When I try passing parameters in, I get an error that says "System.NullPointerException: Attempt to de-reference a null object Class.WebsiteIntegrationService.subscribe: line 11, column 23"
Here's a copy of my Apex Class I am using right now.
My PHP looks exactly like what you have in your post on this thread except I connect to my Org, obviously. Am I referencing the field sub.firstName incorrectly or passing it in incorrectly? PHP below:
The null pointer exception sounds like the arguments aren't getting passed in right. Try calling your subscribe method like so and see if it works any better.
Off the top of my head I don't know the exact syntax, but I think you need to put the parms in a std object before passing them in as an array, or you might need to pass them in as an array in an array.
hemm wrote:
that worked!
Sweet! :smileyhappy:
Hi,
I am trying to access the apex class from jpd file using webservice.
But when i call the webservice method i am getting the Error "Invalid Session header found: Illegal Session"
I've imported BOTH enterprise.wsdl and the wsdl generated from above apex class and using its method as below in JPD file
There is no problem while connecting to SFDC and fetch the result from jpd process but whil calling the above method it failed and server throws "Invalid Session Id"
sObjects urn:sobject.partner.soap.sforce.com
Fields urn:sobject.partner.soap.sforce.com
Faults urn:fault.partner.soap.sforce.com
Might the problem be related to the tapp0-api sandbox server?
I blogged a simple example of how to setup PHP to talk to Apex Web Service that I think should answer most of the questions in this thread. The end result is pretty simple. Bottom line is that you will have your normal $sfdc variable to talk to the regular Salesforce API and you'll be setting up a new SoapClient variable that you will use to communicate with the web services.
http://sfdc.arrowpointe.com/2008/12/05/calling-apex-web-services-from-php/
http://sfdc.arrowpointe.com/2008/12/05/calling-apex-web-services-from-php/
You may something like:
<soap:address location="https://na5-api.salesforce.com/services/Soap/class/[namespace]/[Classname]"/>
and need:
<soap:address location="https://cs2-api.salesforce.com/services/Soap/class/[namespace]/[Classname]"/>
instead.
You'll have to use the the correct server id for your sandbox of course (cs1, cs2, ...).
Ok sure. Could you answer my query on this post regarding the same.
http://community.salesforce.com/sforce/board/message?board.id=apex&thread.id=10423