Abstract

The Force.com REST API provides you with a powerful, convenient, and simple Web services interface for interacting with Force.com. Its advantages include ease of integration and development, and it is an excellent choice of technology for use with mobile applications and Web 2.0 projects.

The REST API is designed to be easily accessible from any programming language – once you understand the basic concepts of the API, you will be able to apply them to PHP, Ruby, .NET, or any other environment.

This tutorial shows you the basics of using the REST API. We walk through a simple Java Web application that authenticates the user to Force.com via OAuth 2.0, then creates, reads, updates, and deletes Force.com Account records via the new API.

Setting up for the Sample Application

If you want an overview of the API, skip ahead to Web Service Authorization with OAuth and Using the Force.com REST API. In this and the following sections, we’ll show you how to run a sample application that uses the REST API.

To get started, you’ll need:

  • A Java application server. The sample code uses some elements of the Java Servlet 3.0 API, supported by app servers, such as Apache Tomcat 7.0.x and Oracle GlassFish Server 3.0.x, but the code can easily be ported to older Servlet technology.
  • The JSON.org Java implementation
  • A Force.com account on EE or DE.

Setup

Enable an SSL endpoint in your application server – instructions for Tomcat.

Create a web application project using your IDE of choice. Set the web application context path to ‘/RestTest’.

Download the JSON.org Java code and add it to the project.

Download the Apache HttpClient 3.1, Apache Logging, and Apache Codec libraries and add them to the project.

Download the REST API sample code (OAuthServlet.java, DemoREST.java, index.html) and add it to the project.

Log in to Salesforce.com with your developer account, navigate to Setup ➤ Develop ➤ Remote Access, and click New to create a new remote access application if you have not already done so.

RemoteAccess.png

If you are running the application server on your own machine (the most common case for a development environment), then the Callback URL will look like http://localhost:8080/RestTest/oauth/_callback. Depending on your configuration, you might need to change the port number. Note – you must use an https Callback URL for servers other than localhost.

After clicking Save, you will see your new application’s credentials:

RemoteAccess2.png

Click the link to reveal the consumer secret. Note – OAuth 1.0 terminology is currently used in the Remote Access screen. The OAuth 2.0 specification uses ‘client’ in place of ‘consumer’.

Copy the consumer key and consumer secret, and paste them into OAuthServlet.java in the existing Servlet initParams:

/**
 * Servlet parameters
 */
@WebServlet(name = "oauth", urlPatterns = { "/oauth/*", "/oauth" }, initParams = {
        // clientId is 'Consumer Key' in the Remote Access UI
        @WebInitParam(name = "clientId", value = "xxxxxxxxxx...xxxxxxxxxx"),
        // clientSecret is 'Consumer Secret' in the Remote Access UI
        @WebInitParam(name = "clientSecret", value = "xxxxxxxxxxxxxxxxxxx"),
        // This must be identical to 'Callback URL' in the Remote Access UI
        @WebInitParam(name = "redirectUri", value = "http://localhost:8080/RestTest/oauth/_callback"),
        @WebInitParam(name = "environment", value = "https://login.salesforce.com"), })
public class OAuthServlet extends HttpServlet {

You must also ensure that the redirectUri in the initParams is identical to the ‘Callback URL’ in the Remote Access UI.

At this point, you are able to build the sample and deploy it to your application server. We will run the application first, then walk through the code to show how it operates.

Running the Sample

You must log out of Force.com prior to running the sample in order to see the flow as described below. It’s also a good idea to restart your browser before you run the sample each time, to clear out session cookies.

Navigate your browser to http://localhost:8080/RestTest/ (or wherever you deployed the web app). You will see the following:

RestTest.png

You will see an error message if the web app is not running on a secure port:

RestTest2.png

If this happens, ensure that you have enabled SSL on your application server and navigate to the secure version of the URL. Click the link and you are taken to the Salesforce.com login page:

Login.png

Login and a screen displays asking you to allow the sample app to access your data:

Authorization.png

This is OAuth in action – you only ever provide your Force.com credentials to the standard salesforce.com authentication website – not to the website requesting access to your data. This authorization page only appears the first time the web application requests access; subsequent sessions require authentication, but skip the authorization step.

On authorizing access to your data, control returns to the sample web app, and it is able to interact with your Force.com data using a token issued during the OAuth process:

Output.png

Note – as mentioned before, this web application is in no way an example of best practices in Java web application design! It exists merely to simply illustrate the process of using OAuth to obtain access to Force.com data, and manipulate that data using the REST API.

Now lets walk through the code, starting with the OAuth Servlet.

Web Service Authorization with OAuth

A common OAuth use case is to allow a third-party website, such as our sample web app, termed the client in the OAuth 2.0 specification, to operate on behalf of a user, without revealing that user’s credentials, such as username and password, to the client. The client first sends the user to an authorization server (login.salesforce.com in our case), which authenticates the user, obtains the user’s authorization, and issues an access token which the client can use in interacting with a resource server (na1.salesforce.com, or whichever instance you are using).

Let’s take a look at the code required for OAuth.

When the Servlet initializes, it constructs authUrl, to which it redirects the user to authenticate and authorize access to data:

authUrl = environment
		+ "/services/oauth2/authorize?response_type=code&client_id="
		+ clientId + "&redirect_uri="
		+ URLEncoder.encode(redirectUri, "UTF-8");

This URL contains the web app’s configuration information that identifies it to Force.com.

The Servlet also creates tokenUrl, which it uses to obtain the access token it needs to use the REST API.

When the user clicks the link in the sample web app home page, they hit http://localhost:8080/RestTest/oauth, and the following code is executed, redirecting them to the authorization URL at Force.com:

// we need to send the user to authorize
response.sendRedirect(authUrl);

Force.com authenticates the user, obtains authorization for the web app to access the user’s data, if necessary, and redirects the user back to redirectUri; in this example, http://localhost:8080/RestTest/oauth/_callback.

When control returns to the Servlet, we use the returned data to build a POST request and send it to tokenUrl. Note – in this, and the other code fragments presented in this guide, error handling is omitted for clarity. The sample code includes required error handling.

System.out.println("Auth successful - got callback");

String code = request.getParameter("code");

HttpClient httpclient = new HttpClient();

PostMethod post = new PostMethod(tokenUrl);
post.addParameter("code", code);
post.addParameter("grant_type", "authorization_code");
post.addParameter("client_id", clientId);
post.addParameter("client_secret", clientSecret);
post.addParameter("redirect_uri", redirectUri);

httpclient.executeMethod(post);

In response, the authorization server supplies us with both an access token and an instance URL wrapped in JSON:

JSONObject authResponse = new JSONObject(new JSONTokener(
        new InputStreamReader(post.getResponseBodyAsStream())));

System.out.println("Auth response: " + authResponse.toString(2));

accessToken = authResponse.getString("access_token");
instanceUrl = authResponse.getString("instance_url");

This is an important step of the OAuth protocol. If the authorization server merely sends the access token directly to the redirect URL, it travels via the user’s browser, and is subject to any vulnerabilities along that path. OAuth specifies that, instead, the authorization server sends a short-lived authorization code to the client, which then invokes the tokenUrl with its shared secret to exchange the code for a longer-lived access token. In this way, the authorization server, client and, ultimately, the resource server, are the only entities that ever see the access token.

Now the sample web app has the access token, it can use it to start interacting with the REST API. First, we save it in the user’s HTTP session, so it can be used by our REST demo Servlet:

// Set a session attribute so that other servlets can get the 
// access token
request.getSession().setAttribute(ACCESS_TOKEN, accessToken); 

// We also get the instance URL from the OAuth response, so set it
// in the session too
request.getSession().setAttribute(INSTANCE_URL, instanceUrl);

Setting a session attribute is more secure than storing the access token in a cookie, since, as a session attribute, it does not travel over the wire to the user’s browser. Now we can redirect the user to our REST demo Servlet, where we show how to use the REST API.

response.sendRedirect(request.getContextPath() + "/DemoREST");

Using the Force.com REST API

Turning our attention to DemoREST.java, we can see the high level structure of the Servlet’s doGet method (again, some error handling is omitted from this code fragment for clarity):

String accessToken = (String) request.getSession().getAttribute(
		ACCESS_TOKEN);

String instanceUrl = (String) request.getSession().getAttribute(
		INSTANCE_URL);

writer.write("We have an access token: " + accessToken + "\n"
		+ "Using instance " + instanceUrl + "\n\n");

showAccounts(instanceUrl, accessToken, writer);

String accountId = createAccount("My New Org", instanceUrl,
		accessToken, writer);

showAccount(accountId, instanceUrl, accessToken, writer);

showAccounts(instanceUrl, accessToken, writer);

updateAccount(accountId, "My New Org, Inc", "San Francisco",
		instanceUrl, accessToken, writer);

showAccount(accountId, instanceUrl, accessToken, writer);

deleteAccount(accountId, instanceUrl, accessToken, writer);

showAccounts(instanceUrl, accessToken, writer);

We display the list of accounts, add a new account named “My New Org”, show its attributes, update its name to “My New Org, Inc”, and finally delete the account. After each operation, we redisplay the account list to show the effect of the change. We’ll look at each operation in turn.

Executing a SOQL Query using the REST API

We execute a SOQL query to obtain the Name and ID fields for all Accounts. The sample uses the Apache HttpClient class for interacting with the REST API, but you can equally use java.net.HttpURLConnection, or any other HTTP client implementation.

HttpClient httpclient = new HttpClient();
GetMethod get = new GetMethod(instanceUrl
				+ "/services/data/v20.0/query");

// set the token in the header
get.setRequestHeader("Authorization", "OAuth " + accessToken);

After creating the necessary HttpClient and GetMethod objects, we set a request header, Authorization to the value OAuth, followed by a space, and the access token. It is essential to do this for every interaction with the REST API; failure to do so results in a 401 ‘Unauthorized’ error when submitting the request.

The REST API accepts SOQL queries via the /services/data/v20.0/query resource. We simply set the ‘q’ parameter to the SOQL query text:

// set the SOQL as a query param
NameValuePair[] params = new NameValuePair[1];

params[0] = new NameValuePair("q",
		"SELECT Name, Id from Account LIMIT 100");
get.setQueryString(params);

httpclient.executeMethod(get);

When we execute the GET operation, the requested URL will be http://na3.salesforce.com/services/data/v20.0/query?q=SELECT%20Name,%20Id%20from%20Account%20LIMIT%20100 - notice that spaces are replaced by ‘%20’, since query parameters must be URL encoded.

If the GET is successful, we will receive a 200 ‘OK’ response and JSON encoded content comprising the results of the query. It is straightforward to navigate the JSON content and display the Id and Name of each account:

JSONObject response = new JSONObject(
		new JSONTokener(new InputStreamReader(
				get.getResponseBodyAsStream())));
System.out.println("Query response: " + response.toString(2));

writer.write(response.getString("totalSize") 
+ " record(s)returned\n\n");

JSONArray results = response.getJSONArray("records");

for (int i = 0; i < results.length(); i++) {
	writer.write(results.getJSONObject(i).getString("Id")
			+ ", "
			+ results.getJSONObject(i).getString("Name")
			+ "\n");
}
writer.write("\n");

The sample code first writes the JSON response to standard output (typically the application server log file – catalina.out in the case of Apache Tomcat) formatted for easy readability:

Query response: {
  "done": true,
  "records": [
    {
      "Id": "0015000000VALDtAAP",
      "Name": "GenePoint",
      "attributes": {
        "type": "Account",
        "url": "/services/data/v20.0/sobjects/Account/0015000000VALDtAAP"
      }
    },
    {
      "Id": "0015000000VALDuAAP",
      "Name": "United Oil & Gas, UK",
      "attributes": {
        "type": "Account",
        "url": "/services/data/v20.0/sobjects/Account/0015000000VALDuAAP"
      }
    },
    ...

Finally the sample code reports the number of records in the query response and iterates through the array of records, writing the ID and Name of each one to the HTTP response that will be sent to the browser:

12 record(s) returned  0015000000VALDtAAP, GenePoint 0015000000VALDuAAP, United Oil & Gas, UK 
...

Creating a Record using the REST API

We can easily create a new Account record by creating our own JSON content and POSTing it to the appropriate URL:

HttpClient httpclient = new HttpClient();

JSONObject account = new JSONObject();

account.put("Name", name);

PostMethod post = new PostMethod(instanceUrl
		+ "/services/data/v20.0/sobjects/Account/");

post.setRequestHeader("Authorization", "OAuth " + accessToken);
post.setRequestEntity(new StringRequestEntity(account.toString(),
		"application/json", null));

httpclient.executeMethod(post);

We create a new JSONObject, and set the minimal data required to create an Account record – the Name field. After creating a new PostMethod with the URL representing the Account record, we simply set the Authorization header as before, add the JSON content via setRequestEntity and execute the POST.

A successful record creation results in a 201 ‘Created’ response code, and JSON content containing more detail, including the new record’s ID. As before, we can easily parse out the data we need:

JSONObject response = new JSONObject(new JSONTokener(
		new InputStreamReader(post.getResponseBodyAsStream())));

accountId = response.getString("id");

Reading a Record using the REST API

As can be seen from the JSON content in the SOQL example above, each Account record (in fact, each record in the system) has an associated Sobject Row URL. This URL acts as a handle for that record for the purposes of read, update, and delete, and has the format:

http://na3.salesforce.com/services/data/v20.0/sobjects/SObjectName/id/

To retrieve a record, simply execute a GET on the appropriate URL, remembering of course to include the access token in the Authorization header:

HttpClient httpclient = new HttpClient();
GetMethod get = new GetMethod(instanceUrl
		+ "/services/data/v20.0/sobjects/Account/" + accountId);

// set the token in the header
get.setRequestHeader("Authorization", "OAuth " + accessToken);

httpclient.executeMethod(get);

As before, we receive JSON formatted content in response:

Query response: {
  "AccountNumber": null,
  "Active__c": null,
  "AnnualRevenue": null,
  "BillingCity": null,
  "BillingCountry": null,
  "BillingPostalCode": null,
  "BillingState": null,
  "BillingStreet": null,
  "CreatedById": "00550000001fg6vAAA",
  "CreatedDate": "2010-10-24T20:49:11.000+0000",
  "CustomerPriority__c": null,
  "Description": null,
  "Fax": null,
  "Id": "0015000000WxaRrAAJ",
  "Industry": null,
  "IsCustomerPortal": false,
  "IsDeleted": false,
  "LastActivityDate": null,
  "LastModifiedById": "00550000001fg6vAAA",
  "LastModifiedDate": "2010-10-24T20:49:11.000+0000",
  "MasterRecordId": null,
  "Name": "My New Org",
  "NumberOfEmployees": null,
  "NumberofLocations__c": null,
  "OwnerId": "00550000001fg6vAAA",
  "Ownership": null,
  "ParentId": null,
  "Phone": null,
  "Rating": null,
  "SLAExpirationDate__c": null,
  "SLASerialNumber__c": null,
  "SLA__c": null,
  "ShippingCity": null,
  "ShippingCountry": null,
  "ShippingPostalCode": null,
  "ShippingState": null,
  "ShippingStreet": null,
  "Sic": null,
  "Site": null,
  "SystemModstamp": "2010-10-24T20:49:11.000+0000",
  "TickerSymbol": null,
  "Type": null,
  "UpsellOpportunity__c": null,
  "Website": null,
  "attributes": {
    "type": "Account",
    "url": "/services/data/v20.0/sobjects/Account/0015000000WxaRrAAJ"
  }
}

The sample code simply iterates over the keys in the JSON content; a real application will use methods, such as getString, to extract the data it requires.

Updating a Record using the REST API

We use the HTTP PATCH method to update individual fields for a record. Since the PATCH method was only recently standardized and is not yet implemented in Apache HttpClient, we dynamically override PostMethod:

PostMethod patch = new PostMethod(instanceUrl
		+ "/services/data/v20.0/sobjects/Account/" + accountId) {
	@Override
	public String getName() {
		return "PATCH";
	}
};

Note – if you are using an HTTP library in which it is not possible to override the method name in this way, you can simply specify PATCH via the _HttpMethod query string parameter as follows:

PostMethod patch = new PostMethod(instanceUrl
		+ "/services/data/v20.0/sobjects/Account/" + accountId 
+ “?_HttpMethod=PATCH”);

Either way, supply the data for the update as JSON content and execute the HTTP request – in our example, we change the Name of the Account and add BillingCity:

JSONObject update = new JSONObject();

update.put("Name", newName);
update.put("BillingCity", city);

httpclient.executeMethod(patch);

Assuming the update succeeds, we receive a 204 ‘No Content’ status code to indicate success with (unsurprisingly) no content to parse.

Deleting a Record using the REST API

Finally, we delete an Account record. As you might guess, we simply use the DELETE HTTP method with the Sobject Row URL:

HttpClient httpclient = new HttpClient();

DeleteMethod delete = new DeleteMethod(instanceUrl
		+ "/services/data/v20.0/sobjects/Account/" + accountId);

delete.setRequestHeader("Authorization", "OAuth " + accessToken);

httpclient.executeMethod(delete);

Force.com REST API Quick Reference

In this article, we've really only scratched the surface of Force.com REST API, focusing on the Query and SObject Row resources. The table below lists all of the supported REST resources in the API in alphabetical order by URI, and provides a brief description for each. In each case, the URI for the resource follows the base URI: http://domain/services/data. The domain might be the Salesforce.com instance you are using, or a custom domain. For example, to retrieve basic information about an Account object in version 20.0: http://na1.salesforce.com/services/data/v20.0/sobjects/Account/.

Resource Name URI Description
Versions / Lists summary information about each Salesforce.com version currently available, including the version, label, and a link to each version's root.
Resources by Version /vXX.X/ Lists the resources available for the specified API version. It provides the name and URI of each resource.
Describe Global /vXX.X/sobjects/ Lists the available objects and their metadata for your organization's data.
SObject Basic Information /vXX.X/sobjects/SObject/ Describes the individual metadata for the specified object.
SObject Describe /vXX.X/sobjects/SObject/describe/ Completely describes the individual metadata at all levels for the specified object.
SObject Row /vXX.X/sobjects/SObject/id/ Accesses individual records from an object based on the specified object ID. You can retrieve or update individual records within a specific object, or delete the specified object.
SObject Blob Retrieve /vXX.X/sobjects/SObject/id/blobField Retrieves the specified blob field from an individual record.
Query /vXX.X/query/?q=soql Executes the specified SOQL query.
Search /vXX.X/search/?q=sosl Executes the specified SOSL search. The search string must be URL-encoded.

See the Force.com REST API Developer's Guide for full details of each resource.

Summary

This tutorial showed how to use the Force.com REST API. The source code demonstrates how to use the API from Java, though the techniques transfer to all other programming languages. After demonstrating how to authenticate and retrieve an access token using OAuth 2.0, we showed how to create, read, update, and delete records using the REST API.

The Force.com REST API is a powerful, convenient, and simple Web services interface for interacting with Force.com. We look forward to seeing our developer community use the REST API to create new innovations around the Force.com platform.

References

About the Author

At the time this article was written, Pat Patterson was a recent addition to the Developer Evangelism team at Salesforce.com, focusing on the Force.com APIs. Describing himself as an 'articulate techie', Pat hacks all manner of code from Ruby web apps down to Linux kernel drivers, writing it all up on the Force.com blog, his own blog Superpatterns, and, of course, Twitter.