Calling a REST Web Service (XML) with Apex

December 4th, 2009

This is a cool little example of calling a REST web service with Apex. You enter your address and the Apex code fetches the geo coordinates from Yahoo! Maps. The service returns the data as XML.

If you want to run this demo in your own org, you will need to do the following:

  1. Add a “Remote Site” (Setup -> Security Controls -> Remote Site Setting) with the URL: http://local.yahooapis.com
  2. Add the XML DOM parser class to your org. It may already be present but if not you can download it from Code Share. Ron Hess’ class makes life much easier than using the standard XmlReader when dealing with XML files.

You can run this example on my Developer Site.

The Visualforce page above presents the user with address fields that they submit to the controller. The controller calls the REST web service and then displays the resulting geo coordinates to the user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<apex:page controller="RestDemoController" tabStyle="Contact">
	<apex:sectionHeader title="Yahoo Maps Geocoding" subtitle="REST Demo"/>
 
     <apex:form >
     <apex:pageBlock >
 
          <apex:pageBlockButtons >
              <apex:commandButton action="{!submit}" value="Submit"
                   rerender="resultsPanel" status="status"/>
          </apex:pageBlockButtons>
          <apex:pageMessages />
 
          This example calls Yahoo! Map geocoding REST service with the address
          you provide below.<p/>
 
          <apex:pageBlockSection >
               <apex:pageBlockSectionItem >
                    <apex:outputLabel for="address">Address</apex:outputLabel>
                    <apex:inputText id="address" value="{!address}"/>
               </apex:pageBlockSectionItem>
          </apex:pageBlockSection>
 
          <apex:pageBlockSection >
               <apex:pageBlockSectionItem >
                    <apex:outputLabel for="city">City</apex:outputLabel>
                    <apex:inputText id="city" value="{!city}"/>
               </apex:pageBlockSectionItem>
          </apex:pageBlockSection>
 
          <apex:pageBlockSection >
               <apex:pageBlockSectionItem >
                    <apex:outputLabel for="state">State</apex:outputLabel>
                    <apex:inputText id="state" value="{!state}"/>
               </apex:pageBlockSectionItem>
          </apex:pageBlockSection><br/>
 
          <apex:actionStatus id="status" startText="Fetching map..."/>
          <apex:outputPanel id="resultsPanel">
               <apex:outputText value="{!geoAddress}"/>
          </apex:outputPanel>
 
     </apex:pageBlock>
     </apex:form>
 
</apex:page>

The submit method below is invoked from the Visualforce page when the user clicks the submit button. It passes the address info to the getMap method which does the GET call to the REST service. We use the XmlDom class to parse through the results and construct a GeoResult object (from the inner class) and then present the info as a String to the user on the Visualforce page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class RestDemoController {
 
	public String geoAddress {get;set;}
	public String address {get;set;}
	public String city {get;set;}
	public String state {get;set;}
 
    // set the Yahoo Application Id
    private String appId {get;set { appId = 'DaqEkjjV34FCuqDUvZN92rQ9WWVQz58c0WHWo2hRGBuM310.qXefuBVwvJQaf1nnMCxSbg--'; } }
 
    // method called by the Visualforce page's submit button
    public PageReference submit() {
    	List<GeoResult> results = getMap(address,city,state);
    	geoAddress = results[0].toDisplayString();
    	return null;
    }
 
    // call the REST service with the address info
	public List<GeoResult> getMap(String street, String city, String state) {
 
		HttpRequest req = new HttpRequest();
		Http http = new Http();
		List<GeoResult> results = new List<GeoResult>();
 
		// set the request method
		req.setMethod('GET');
 
		// set the yahoo maps url with address
		String url = 'http://local.yahooapis.com/MapsService/V1/geocode?appid=' + appId
			+ '&street=' + EncodingUtil.urlEncode(street,'UTF-8')
			+ '&city=' + EncodingUtil.urlEncode(city,'UTF-8')
			+ '&state=' + EncodingUtil.urlEncode(state,'UTF-8');
 
		// add the endpoint to the request
		req.setEndpoint(url);
 
		// create the response object
		HTTPResponse resp = http.send(req);
 
		// create the xml doc that will contain the results of the REST operation
		XmlDom doc = new XmlDom(resp.getBody());
 
		// process the results
		XmlDom.Element[] elements = doc.getElementsByTagName('Result');
		if (elements != null) {
			for (XmlDom.Element element : elements)
				results.add(toGeoResult(element));
		}
 
		return results;
	}
 
	// utility method to convert the xml element to the inner class
	private GeoResult toGeoResult(XmlDom.Element element) {
 
		GeoResult geo = new GeoResult();
		geo.latitude = element.getValue('Latitude');
		geo.longitude = element.getValue('Longitude');
		geo.address = element.getValue('Address');
		geo.city = element.getValue('City');
		geo.state = element.getValue('State');
		geo.zip = element.getValue('Zip');
		return geo;
	}
 
	// inner class
	private class GeoResult {
 
		public String latitude;
		public String longitude;
		public String address;
		public String city;
		public String state;
		public String zip;
		public String toDisplayString() {
			return address + ', '
			+ city + ', '
			+ state + ', '
			+ zip + ' ['
			+ latitude + ', '
			+ longitude + ']';
		}
 
	}
 
}
VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Categories: Apex, Code Sample, Salesforce, Visualforce

Leave a comment

Comments Feed8 Comments

  1. Wes

    Nice one :) I think I’m gonna have to use this example to change my Flickr lib to use REST instead of SOAP.. seems the XMLStreamReader (and therefore XMLDom) have some issues parsing certain chars.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  2. jeffdonthemic

    I was thinking about doing a Flickr demo Wes but thought that was more of your baliwick.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  3. Problems Parsing JSON Responses with Apex « Jeff Douglas – Technology, Coding and Bears… OH MY!

    [...] on December 28, 2009. Filed under: Apex, Salesforce | A couple of weeks ago I wrote an article and small demo of a REST web service call returning XML. It was my intention to do the same demo using JSON. [...]

  4. Calling a REST Web Service (JSON) with Apex | Jeff Douglas - Technology, Coding and Bears... OH MY!

    [...] 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 [...]

  5. Tom

    This is great stuff! Looking all over for sample like this. Is there a location where we can find other examples like this? Book, blog? Thanks so much.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  6. amruta

    Hi !
    I am trying to create FusionCharts with the data from Visualforce. Is there a blog i can refer? Thanks!

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  7. Rajan

    Thanks for post. I am getting following error,

    Invalid Type XMLDom.Element at following line

    // process the results
    XMLDom.Element[] elements = doc.getElementsByTagName(‘Result’);

    I can see that Element is inner class and I am using salesforce 20.0 api

    Any suggestion

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  8. Steve

    Works for me… Thanks Jeff.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)

Leave a comment

Feed

http://blog.jeffdouglas.com / Calling a REST Web Service (XML) with Apex