rest_area

Accessing Apex REST from Site.com

Site.com is a Content Management System (CMS) provided by Salesforce.com that allows non developers to build sites through the use of a GUI interface known as the Site.com Studio.  Site.com provides data services page elements that provide a way to retrieve data from Salesforce.  However, sometimes the information needed may be more complex and not be able to be retrieved easily (or at all) via the provided data services.  If you are working in a community it may be possible to just use a Force.com Site page to meet the requirement; however, if it is not possible, one option to consider is calling a public Apex REST resource from a Site.com page.

This article documents how to set up a public REST resource and then use it in a Site.com page.  A simple example page that gets message data (a simple custom class) and displays it on the page is used to illustrate the concepts.  All code in this article is available on GitHub.

Parts of setting up a public REST resource and exposing it through a Force.com site is described in this article by Pat Patterson.  I highly recommend it and used it as a reference.

Overall Design

Due to the same-origin policy, the Apex REST resource cannot be called directly from the JavaScript in a Site.com page.  JSONP is used to work around the same origin policy. The Apex REST method queries some recent chatter posts and creates a simple list of Message objects (a custom class) to return, wrapped in the callback specified as a parameter to the method.

Apex REST class

The Apex class defines the following method to process the GET requests.

It gets the callback function that is defined by the calling client from a parameter named ‘callback’ and builds the messages.  After that it constructs the RestResponse with a content type of application/javascript, which is appropriate for JSON, and then sets the responseBody to the messages JSON wrapped in the callback function.

The Apex Class must be added to the Force.com Site’s public profile.  The profile can be edited by clicking the Public Access Settings button on the Site Details page.

The Resource URL

The resource must be accessed through the Force.com Site’s URL (e.g., www.mysite/services/…) and not through the Salesforce instance URL (e.g., na1.salesforce.com/services/…).  Accessing the resource through the Salesforce instance URL requires the user to have a valid session, which a public user will not have, so the data will not be able to be retrieved. Accessing it through the Force.com Site URL does not require that.  For example, on a developer edition with a Force.com Site with a path of ‘test’ the full path could be ‘abc-developer-edition.na15.force.com/test/services/apexrest/v1.0/messages.

The JavaScript

JavaScript must be added to the page (or page template) in Site.com to retrieve the data.  A library such as jQuery can be used to make the JSONP interaction take place at a higher level of abstraction.  The jQuery ajax function (or related functions) will load data from a URL.  Site.com allows you to set Custom Properties.  This is an ideal place to store the resource URL, so that it is not hardcoded into the page.  In the code below see the url value being set to {!Site.messageURL}.  The messageURL property is set to the absolute path of the REST URL.  If you do not specify the protocol the browser thinks it is a relative URL.  In a developer edition org it could be something like //abc-developer-edition.na15.force.com/test/services/apexrest/v1.0/messages.  Note the leading double slashes. That directs the browser to load the resource using the browser’s protocol being used for the current page.  That will allow the page to work in preview mode inside the Site.com studio where the protocol is https and when regularly accessed outside the studio after being published, using http.

The following JavaScript is placed in the page’s header markup.  Note that you can put it in a JS file instead, which is generally a best practice. For simplicity I put it in the page.

The jQuery framework handles all the dirty work of the JSONP and allows the developer to simply define a success handler. The handler simply builds an unordered list from the messages and sets the HTML of an existing element to be the list.  The element was a simple content block with an id of messages specified, but could be any element that allows an id to be specified.

Deployments

Care must be taken with deployments.  It is typical that a Site.com site is edited directly in production (until recently that was the only choice).  However, it is not possible (thank goodness!) to edit Apex code directly in production.  The Apex code should be deployed prior to the Site.com page being published.  The page can then be viewed in the preview mode, and verified for correctness, before publishing it.

Conclusion

This post used a simple example to outline how to access Apex REST resources from Site.com.  This technique should not be used as an initial choice, but only after built-in Site.com constructs have been ruled out.

All code in this article is available on GitHub.