Thursday, May 23, 2013

Calling a REST Web Service (JSON) with Apex

Calling a REST Web Service (JSON) with Apex

Using JSON RESTful Web Services with Salesforce.com opens up your org to a number third-party integration opportunities (Google, Yahoo!, Flickr, bespoke, etc.). JSON support isn't baked into the Force.com platform but Ron Hess at Salesforce.com has created a JSON parser which will do the heavy lifting for you.

Last month I wrote a blog post and example of how to call a REST Web Service with Apex that returns and consumes XML. It was my intention to do the same demo using JSON, however, I ran into a small sang. I couldn’t get the Apex JSONObject parser to work. I tried on and off for a couple of days but couldn't beat it into submission. I checked around the twitter-verse and no one reported much success using the JSON parser with complex objects. I finally cried "uncle" and called Ron and asked for help. Ron was extremely responsive and over the course of a couple of days we worked worked through some of the parsing issues and finally updated the Google project with the changes.

I put together a small demo where you enter your address and the Apex code fetches the address and coordinates from the Google Maps . The service returns the data as a JSON object. You can run this example on my Developer Site.

To get started, you'll need to download the JSONObject class and install it into a Developer org or Sandbox. Unfortunately there is no documentation for the parser so you have to extrapolate from the json.org website.

You'll also need to sign up for a Google Maps API key in order to use their geocoding service. I would also recommend that you take a look at the docs for Google Maps geocoding service.

Here is the Controller for the demo. The interesting stuff is in the getAddress() and toGeoResult() methods. In getAddress(), the user-entered address is used to construct the URL for the GET call to the geocoding service. Make sure you properly encode the address or you may receive undesirable results returned from Google. One thing to point out is line #58. Google is returning a line feed in their JSON response which causes the JSON parser to choke. I simply replace all like feeds with spaces and that did the trick. Ron was going to look into making this change to the JSONObject class in the near future.

I was also having some problems with the geocoding service so I hard-coded the returned JSON object for testing. I checked around and it seems to be a common problem that the Google Maps API randomly returns 620 errors when overloaded. You might want to take a look at the JSON response returned for the hard-coded address. I will give you a little insight for the parsing process.

The toGeoResult() method parses the returned JSON response and populates the GeoResult object with the appropriate data. I chose this Google Maps example because it shows how to parse simple values, nested JSON objects and arrays. The coordinates for the address can either be returned as integers or doubles so I have to check each one.


The Visualforce page is fairly simple and presents the user with a form to enter their address. If the geocoding services is experiencing issues, the user can check "Use hard-coded Google JSON response?" and the Controller with use the hard-coded JSON response instead of making the GET call to the geocoding service. Once submitted, the address is processed and the outputPanel is rerendered with the resulting address and coordinates.



No comments :

Post a Comment

Labels

visualforce page ( 13 ) apex integration ( 5 ) apex trigger ( 4 ) csv file from vf page ( 4 ) javascript ( 4 ) csv visualforce page ( 3 ) Too many ( 2 ) call out ( 2 ) integration ( 2 ) rest api ( 2 ) salesforce rest api ( 2 ) salesforce to salesforce integration ( 2 ) sfdc rest api ( 2 ) trigger ( 2 ) 15 digit to 18 digit ( 1 ) DML rows in Apex ( 1 ) Date Conversion ( 1 ) Date/Time conversion ( 1 ) Deploy ( 1 ) Objects to Future Annotated Methods ( 1 ) SFDC limits ( 1 ) Sobject to Future Annotated Methods ( 1 ) Test Class ( 1 ) TimeZone Conversion ( 1 ) Too many dml rows ( 1 ) Too many future calls ( 1 ) annotations ( 1 ) apex code ( 1 ) closed opportunities ( 1 ) commit ( 1 ) convert ( 1 ) create records ( 1 ) csv create records ( 1 ) custom setting ( 1 ) deployment ( 1 ) deployment changeset ( 1 ) disable apex class ( 1 ) disable apex trigger ( 1 ) disable in production ( 1 ) document ( 1 ) download ( 1 ) field name ( 1 ) formula fields ( 1 ) iframe ( 1 ) inactive ( 1 ) intellisense ( 1 ) jsforce ( 1 ) limits ( 1 ) matrix report in vf page ( 1 ) multi select ( 1 ) multi select salesforce ( 1 ) multiselect ( 1 ) paypal ( 1 ) picklist ( 1 ) record type ( 1 ) rollback ( 1 ) salesforce limits ( 1 ) salesforce list ( 1 ) salesforce map ( 1 ) salesforce rest ( 1 ) salesforce set ( 1 ) salesforce1 ( 1 ) sandbox deployment ( 1 ) sfdc collection ( 1 ) sfdc list ( 1 ) sfdc map ( 1 ) sfdc rest ( 1 ) sfdc set ( 1 ) uncommitted ( 1 ) updated field ( 1 ) user ( 1 ) validation rule opportunity ( 1 ) validation rules opportunities ( 1 ) vf page ( 1 )

Ad