Building a Force.com API Explorer in 30 Lines of Code

miniexplorer3

There are several robust and well established API explorers out there (here and in the Force.com IDE), and this is by no means meant to be a replacement or even an alternative.

When I start exploring new APIs, I like to have a simple way to invoke methods and get the raw JSON back so that I know exactly what the response looks like and how to handle it in my application. I could use curl or other similar tools, but building an app is also a good exercise to identify the minimalistic code infrastructure required to get the “authenticate > get access token > make API calls” workflow going.

It turned out to be very easy to do using the ForceTK library, so I thought I’d share this mini API Explorer here.

The 30 Lines of Code

var clientId = 'YOUR_CONSUMER_KEY_HERE',
    loginUrl = 'https://login.salesforce.com/',
    redirectURI = 'http://localhost:3000/oauthcallback.html',
    proxyURL = 'http://localhost:3000/proxy/',
    client = new forcetk.Client(clientId, loginUrl, proxyURL);

function loginDialogCallback(response) {
    if (response && response.access_token) {
        client.setSessionToken(response.access_token, null, response.instance_url);
    } else {
        alert("Authentication Error: No Token");
    }
}

$('#btn-login').click(function() {
    var url = loginUrl + 'services/oauth2/authorize?display=popup&response_type=token' +
        '&client_id=' + encodeURIComponent(clientId) + '&redirect_uri='+encodeURIComponent(redirectURI);
    window.open(url, 'login', 'width=700,height=600');
});

$('#btn-exec').click(function() {
    client.query($('#query').val(),
        function (data) {
            $('#result').html(JSON.stringify(data, undefined, 3));
        },
        function (error) {
            alert("Error: " + JSON.stringify(error));
        });
    return false;
});

Code highlights:

  1. To login (line 15), open a window with the Salesforce login URI, your client id, and your redirect URI.
  2. When the OAuth process completes, your oauth callback page calls the loginDialogCallback() function (line 7) with the access token (more on this below). You pass that information to the ForceTK client (line 9).
  3. You can now start executing queries using the ForceTK client’s query() function (line 22).

A version of this code with a few additional bells and whistles is available here.

Handling the OAuth Response

OK, there is just a little more code… At the end of the OAuth workflow, the Salesforce authentication process loads the redirect URI you specified in your Connected App and passes the access token and other OAuth values (server instance, refresh token, etc.) in the query string. Your redirect URI page simply needs to parse the query string, extract the access token and the other OAuth values, and pass that information back to your application by invoking its loginDialogCallback() function.

Here is the code for oauthcallback.html:

<html>
<body>
<script>

if (window.location.hash) {
    var message = decodeURIComponent(window.location.hash.substr(1)),
        params = message.split('&'),
        response = {};
    params.forEach(function (param) {
        var splitter = param.split('=');
        response[splitter[0]] = splitter[1];
    });
    window.opener.loginDialogCallback(response);
    window.close();
}

</script>
</body>
</html>

A Node.js Proxy

Because of the browser’s cross-origin restrictions, your JavaScript application hosted on your own server (or localhost) will not be able to make API calls directly to the *.salesforce.com domain. The solution is to proxy your API calls through your own server.

Node.js and the “request” module make it really easy to create a proxy server. Here is the code:

var express = require('express'),
    http = require('http'),
    request = require('request');

var app = express();

app.use(express.static(__dirname + '/client'));

app.all('/proxy', function(req, res) {
    var url = req.header('SalesforceProxy-Endpoint');
    console.log("proxying: " + url);
    request({ url: url, headers: {'Authorization': req.header('X-Authorization')} }).pipe(res);
});

console.log('Listening on port 3000...');
http.createServer(app).listen(3000);

In addition to proxying your API calls, this server also works as an HTTP server to serve your application static resources located in the “client” folder (line 7).

This environment is meant as a test platform on localhost, and not as a production proxy server.

Installing and Running the App

  1. Download the code here and unzip the file anywhere on your file system.
  2. Login to your development environment.

    You can sign up for a free developer environment here if you don’t already have one.
  3. Create a Connected App (Left Nav > Build > Create > Apps > Connected Apps > New) defined as follows:

    ConnectedApp

  4. After saving your Connected App, copy the consumer key to your clipboard.
  5. Open the force-api-mini-explorer/js/app.js file and paste the consumer key as the value for clientId on line 2.
  6. Open a command prompt (terminal), cd to the force-mini-api-explorer folder, and type the following to install the Node.js modules required by the proxy server (express and require):
    npm install
    
  7. Start the server:
    node server
    
  8. Open a browser and access the following url: http://localhost:3000.
  9. Click the Login button and authenticate.
  10. Type a SOQL query and click the Run Query button.

Summary

There is no rocket science here, just a quick and easy way to set up ForceTK, get familiar with the APIs, and run a development environment for JavaScript apps that are not hosted in Visualforce pages. The code is maintained in this repository on GitHub.

6 Responses to Building a Force.com API Explorer in 30 Lines of Code

  1. Colin February 7, 2014 at 3:58 pm #

    As someone who has been unfortunate enough to have built a saleforce app in the past, I think this post is awesome in it’s detail and simplicity!

    Thanks for sharing Christophe.

  2. Bruno February 7, 2014 at 5:08 pm #

    A very nice example! Thanks for sharing Christophe!! Will help me with some new ideas!

  3. Christophe Coenraets February 7, 2014 at 5:12 pm #

    Thanks Colin & Bruno. Glad it’s helpful.

  4. robin February 19, 2014 at 9:17 am #

    Why do I get the data same as your sample after installing and running the app?

  5. Harshit March 1, 2014 at 12:24 am #

    Christophe,

    I have question for fairly similar application I am building here, this is an html page that uses jscript.

    Instead of node, I have an html page which use forcetk.js for oAuth2, while defining the connected app in salesforce to generate client id, I just want to know what has to be my redirect url – I want to user to land on a custom page called ‘editor.html’ after login

    In your case, you are redirecting to localhost:3030 which is port of node app, I read documentation for redirect url it says

    To protect the authentication code, the Callback URL cannot have ‘http’ as its scheme – it must be ‘https’ or a custom URI scheme (often used in the user-agent flow to pass control back to a native application). After entering your application’s details and clicking Save

    To redirect user to something like app/editor.html what should be redirect url – please advice If am wrong in understanding here

    http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com

  6. Harshit Pandey (@OyeCode) March 2, 2014 at 5:07 am #

    Christope,

    Just like to share this with you, while doing

    $npm install .

    I found an Node.js error shown here, you can add this note or workaround to save the time of other readers

    module.js:340
    throw err;
    ^
    Error: Cannot find module ‘express’
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object. (C:\ChatServer\Server\server.js:6:9)
    at Object. (C:\ChatServer\Server\server.js:25:4)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)

    I fixed the issue here by installing express locally to by running directory through

    $ npm install express

    Better explanation about global -g and local installation I found here

    http://stackoverflow.com/questions/17162308/node-js-error-cannot-find-module-express

Leave a Reply

css.php