Tl_web_api_icon This is part one of a three part series showing how to call the Force.com REST API from JavaScript in various scenarios. Part two, Calling the REST API from JavaScript… from Anywhere!, explains how to call the REST API from JavaScript served from a domain outside Force.com, while part three, Calling the REST API from JavaScript in PhoneGap, looks at JavaScript running in mobile apps on the PhoneGap framework.

One of the great things about working in the Force.com developer evangelism team is the cross-pollination of ideas. Prompted by some questions in the Developer Boards, a couple of us have been trying different approaches to allow JavaScript code to call the Force.com REST API, working around the restrictions imposed by the same origin policy. I did some work using a simple PHP proxy, hosted, with my JavaScript, on a separate site, while Sandeep tried out YQL, but neither solution was particularly satisfying – my proxied approach required a separate host, while Sandeep’s had all the data flowing through Yahoo.

It was a chance remark by Sandeep that prompted me to look to the AJAX Toolkit, a wrapper for the SOAP API, for inspiration. The AJAX Toolkit provides a JavaScript library and SOAP endpoint on the same host as your Visualforce page; unfortunately, the corresponding REST endpoint does a redirect to the canonical URL, which doesn’t work for my purposes, since it breaks same origin policy, but, looking at the AJAX Toolkit, I noticed the AJAX Proxy, a component designed to allow your JavaScript to call out to API endpoints outside the Force.com platform.

With some lateral thinking and Josh‘s recent Cookbook recipe Using jQuery in a Visualforce Page as a guide, I was able to quickly repurpose my proxy-based approach to use the AJAX Proxy to call the REST endpoint, and, in a couple of hours, had a JavaScript app running with describe, query, create, retrieve, update and delete all operational, allowing you to write code like this:

// Get a reference to jQuery that doesn't conflict with Visualforce
$j = jQuery.noConflict();
// Get an instance of the REST API client
var client = new forcetk.Client('{!$Api.Session_ID}');
// Get an account name and put it somewhere on the page
client.query("SELECT Name FROM Account LIMIT 1",function(response){
    $j('#accountname').html(response.records[0].Name);
});

You can find the embryonic project at GitHub – it’s currently in my own profile – we’ll move it over to the DeveloperForce profile as it matures. If you’ve been waiting for a way to call the Force.com REST API from JavaScript, go take a look and see if it meets your needs.

UPDATE – here’s a brief video showing the toolkit in action.

tagged , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • http://blog.superpat.com/ Pat Patterson

    As Quinton mentioned, this should fit neatly with jQuery Mobile. More on that soon!

  • http://profile.typepad.com/stomita Stomita

    I’m wondering why they don’t have the API endpoint in the same origin of VF, as the SOAP API does ? Otherwise, the REST API endpoint might offer crossdomain opt-in like setting crossdomain.xml or XHR level2 Access-Control-Allow-Origin ?

  • http://profile.typepad.com/guptaabhinav Abhinav Gupta

    You know I tried and failed on my REST experiment for the same reasons. Its really great to see this working now via /services/proxy available internally. Good going guys !

  • Stephan Morais

    Another option worth noting is to use JavaScript remoting for Apex controllers. See:
    http://blog.sforce.com/sforce/2011/02/quick-look-into-javascript-remoting.html

  • http://blog.superpat.com/ Pat Patterson

    Stomita – I think the original driver for the REST API was external sites calling in. If/when we fix this, it’s a simple change to the toolkit code to use the VF endpoint directly, avoiding the extra hop.
    Abhinav – Thanks :-)
    Stephan – You’re absolutely correct – the developer can decide on client or server side processing – we make both available.
    All – I just pushed another sample to the GitHub project – https://github.com/metadaddy/Force.com-JavaScript-REST-Toolkit/blob/master/mobile.page – an HTML5 mobile app, using jQuery Mobile. Have fun!

  • http://profile.typepad.com/shedal Shedal

    Pat, you didn’t answer Stomita’s question. I’m still wondering why doesn’t REST API support CORS? It’s so easy to just add an HTTP header:
    Access-Control-Allow-Origin: *
    And then cross-domain JS calls would work like a charm in all modern browsers.

  • http://blog.superpat.com/ Pat Patterson

    Hi Shedal, we’re evaluating CORS for a future release.

    • http://twitter.com/fgwarb fgwarb

      Hello Pat,
      Was there a decision on CORS? (In context of Apex Rest classes) I think it’s supported, just looking for confirmation somewhere online.

      • http://blog.superpat.com/ Pat Patterson

        No – no support yet as far as I know. What makes you think there is?

  • Alan

    Apologies if this is already obvious, but will this approach work for a page I serve up on my own server that talks to Salesforce? My page is not a Visualforce page but standard jsp/html residing on our own server, that calls out to the SF Rest API. I’ve hit a stumbling block with cross domain ajax calls.
    Thanks

  • http://blog.superpat.com/ Pat Patterson

    Hi Alan – I wrote a follow-up blog entry that covers accessing the REST API from JavaScript served from your own domain – http://blog.sforce.com/sforce/2011/04/calling-the-rest-api-from-javascript-from-anywhere.html – and another on JavaScript in PhoneGap – http://blog.sforce.com/sforce/2011/05/calling-the-rest-api-from-javascript-in-phonegap.html – I’ll update the three blog entries to reference each other.

  • Alan

    Hi Pat,
    Thanks for posting those links.
    Just to be clear, for externally hosted Javascript, does the approach you have outlined require deploying a proxy? The following from the first link seems to imply that:
    “Alternatively, to host JavaScript outside the Force.com platform, we can deploy a simple PHP proxy to perform the same function as the AJAX proxy.”
    Thanks

  • http://blog.superpat.com/ Pat Patterson

    Hi Alan, yes – that’s exactly correct – JavaScript uses XMLHttpRequest to access APIs such as the Force.com REST API. The XMLHttpRequest specification (http://www.w3.org/TR/XMLHttpRequest/) mandates that connections can only be made to the same origin (host, port, protocol) that served the HTML page. Running a proxy in the same origin allows you to connect to the Force.com REST API via that proxy.
    As has been mentioned in other comments here, there is a specification, CORS (http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing) that allows a service to loosen that policy in a controlled way. This is something we are considering for the future.

  • Alan

    Hi Pat,
    Thanks, I’m aware of the CORS spec.
    If possible we’d like to avoid the proxy solution.
    Would the following scenario be workable- deploy a VF page that contains an IFrame serving up a page from our server, possibly with an embedded hidden IFrame from Salesforce.
    Like this:
    Container Page from http://www.salesforce.com
    IFrame containing http://www.myserver.com
    Embedded HIdden IFrame from http://www.salesforce.com
    Thanks

  • http://blog.superpat.com/ Pat Patterson

    Hi Alan, I don’t think that would work, since communication between iframes containing pages from different domains is very limited.

  • John Jordan

    Hi Pat, the examples page listed on here https://github.com/developerforce/Force.com-JavaScript-REST-Toolkit/blob/master/README.markdown seems to be a broken link now.
    I was unable to find any documentation or sample code showing create / update event methods using the REST Toolkit (got query’s and descriptions examples working on my org really nicely thought).
    I am kind of new to the API but have a fair bit of JS and SF experience, am hoping to use your tool to allow me to do some fancy AJAX / Chatter integration.
    Thanks for providing a great tool!

  • http://blog.superpat.com/ Pat Patterson

    Hi John – I just checked that link and it looks fine to me – could you check it again? What error do you get?

  • Robert Sösemann

    Hy Pat,

    I just placed my question

    http://boards.developerforce.com/t5/REST-API-Integration/ExtJS-Grid-with-REST-Proxy-always-gets-a-302-Found-when-connect/m-p/381877

    in the force.com community when I found out that you spend a lot of time and effort into what I am trying to do…
    I want to create a Visualforce component which displays sobjects in an excel like grid (i choose ExtJS4 Grid), makes them sortable, editable, ….

    As I am quite new to Force.com API stuff and even more new to ExtJS I was not able to make perfect sense from your posts.

    Is my approach wrong to create custom Apex REST Service for generic SObject CRUD and just connecting this to ExtJS. ExtJS is doing this crud on its own and I do not understand hwo to fit your toolkit in.

    Can you give me some directions?

    Thanks in advance and best regards,

    Robert

    • http://blog.superpat.com/ Pat Patterson

      Hi Robert,

      I took a look at your discussion board post, and it looks like you’ve made some progress. I haven’t used ExtJS, but you should be able to use the forcetk.js wrapper to get JSON data via the proxy and pass it to ExtJS. As you identify in your post there, you would have to use a query to get all the objects of a given type – your Apex REST method is a good approach to presenting the interface you need, I think.

      Cheers,

      Pat

  • Jody Brooks

    Hi, can you direct me to where you define which versions of jquery-ui, template.js, and jquery.js you used. I’m encountering errors that many suggest are version-related.

    Specifically, when I run the example.page, I get an error that:

    $j(“”).dialog is not a function

    This is despite the fact that I’ve confirmed the latest version of jquery-ui.js and jquery-ui.css is being loaded.

    Thanks.