Plug and SocketLongtime readers may remember the series of posts I wrote in early 2011 on calling the Force.com REST API from JavaScript running on Visualforce, off-platform web pages, and PhoneGap hybrid apps. Those posts spawned the Force.com JavaScript REST Toolkit (in particular, forcetk.js), which, in turn, became part of the Salesforce Mobile SDK.

While JavaScript Remoting (see also the blog post on RemoteTK) is a more efficient mechanism for accessing data in Force.com from JavaScript, since it doesn’t consume API calls, it’s still sometimes useful to be able to call the APIs from JavaScript. One of the tasks that forcetk.js performs is to route API calls via the Ajax Proxy, since the REST API is not exposed on Visualforce servers, and JavaScript’s Same Origin Policy prevents us from calling it directly.

Correction – the REST API wasn’t exposed on Visualforce servers. From Summer ’13, it is!

Now you can access REST API URLs directly from JavaScript on Visualforce. Here’s a minimal example:

<apex:page>
  <apex:includeScript value="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"/>
  <script>
    jQuery(document).ready(function($) {
      // Pull 10 Accounts via the REST API
      $.ajax('/services/data/v28.0/query?q=SELECT+Name+FROM+Account+LIMIT+10',
        {
          beforeSend: function(xhr) {
            // Set the OAuth header from the session ID
            xhr.setRequestHeader('Authorization', 'Bearer {!$Api.Session_ID}');
          },
          success: function(response) {
            // We got 'em - append our records to the HTML list
            $.each(response.records, function(index, record) {
              $('#accountList').append('<li>'+record.Name+'</li>');
            });
          },
          error: function(jqXHR, textStatus, errorThrown) {
            // Oops - what went wrong?
            alert(jqXHR.status + ': ' + errorThrown);
          }
        }
      );
    });
  </script>
  <h1>Test REST API Without Proxy</h1>
  <p>10 Accounts:</p>
  <ul id="accountList">
  </ul>
</apex:page>

With the result:

Test REST API Without Proxy

I need to do some more rigorous testing before I remove the call to the Ajax Proxy from forcetk.js, but I wanted to share this nugget today, since it’s immediately useful in answering this question on Salesforce StackExchange. In the meantime, if you want to give this a quick try with a Visualforce page that is using ForceTK, insert the following code after the call to client.setSessionToken('{!$Api.Session_ID}');

    client.proxyUrl = null;
    client.instanceUrl = '';

This should work – let me know in the comments if you encounter any problems!

UPDATEhere’s a Visualforce page that lets you execute arbitrary REST queries.

Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • mohit srivastav

    Brilliant!Thanks !This opens up lot of possibilities !

  • http://www.tgerm.com/ Abhinav Gupta

    Thanks for this update, it might help on some odd and RESTful day !
    Still, if REST api calls from VF still count against the quota, I would give first shot with remotetk #remotingiscool !

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

      See my reply to ‘Phil’ – there are operations that are possible via the APIs that are not available from Apex – for example, the Tooling API.

      • http://www.tgerm.com/ Abhinav Gupta

        Thanks @metadaddy:disqus and good catch about Tooling REST API !

  • Phil

    Very cool! What is good use case for using this instead of Javascript remoting?

    • Chris Wall

      Good question. I’d say that the REST API may be easier to integrate w/ a 3rd-party Javascript (like jquery, shown above), particularly if you’re using the framework to develop the UI. At the same time, remoting works well w/ jquery and Knockout and other template-based frameworks.

      Remoting is easier to use, overall, and, depending on what you’re doing and when comparing apples-to-applies, remoting should be a tad faster.

      Note: Remoting now supports OAuth.

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

      You can perform some operations via the API that are not possible from Apex, for example, get the source of an Apex Trigger: /services/data/v28.0/sobjects/ApexTrigger/[TRIGGER_RECORD_ID]?fields=Body

  • Anonymous

    Cool! good to know

  • Prafulla Patil

    This is huge!, Thanks a lot for posting.

  • Raj Chilukuri

    This is nice. Do we know if this will count against callout Limits?

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

      This is not a callout, since the client is the browser, rather than Apex code, so, no, it will not impact callout limits. It will, however, consume API calls.

  • mohit srivastav

    Sometimes we have chatter API’s where data is exposed through REST API and same we cannot query in apex and use javascript remoting.I would use this instead!

  • Thomas Gagne

    What about calling our application’s own REST methods inside /service/apexrest ? It would be nice, on occasion, to not have to define the controller inside the code. There are times, like inside buttons, were we haven’t the privilege of defining a controller and yet may still want to call our own services.

    Just in-case, I tried the code below, and it still doesn’t work. I suspect that means that for our own REST services we must still use sforce.connection.retmoeFunction().

    function test(employeeId) {
    xhr = new XMLHttpRequest();
    xhr.open( “GET”, “/services/apexrest/Employee?id=” + employeeId, false);
    xhr.setRequestHeader(“Authorization”, “Bearer ” + “{!$Api.Session_Id}”);
    xhr.send();
    }
    test(’99999′);

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

      You’re correct – only /services/data is currently exposed, so you’ll need to use @remoteAction methods in the controller. I’ll open a request for /services/apexrest also, for added flexibility.

  • Mike Tetlow

    This is especially powerful when coupled with the new ability to describe page layouts (Another Summer ’13 feature). Previously, there was no way to do this via an APEX describe. Now you can drop the data directly to the client side and mix / match your fields together to generate a custom page generated by VF / JS, which is influenced by the Page Layout.

    The REST method for this is:

    /services/data/v28.0/sobjects/CustomObj__c/describe/layouts

  • Raymond Gao

    Nice work! you can use JSONP for remote REST api calls. Can you please explain how one might do testing with the toolkit? And, how does it relate to SF Canvas toolkit, since it also uses Javascript?
    Thanks,