Salesforce SOQL 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'),
    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, 
              method: req.method, 
              json: req.body, 
              headers: {'Authorization': req.header('X-Authorization')}})
        .pipe(res);
});

app.set('port', process.env.PORT || 3000);

app.listen(app.get('port'), function () {
    console.log('Express server listening on port ' + app.get('port'));
});

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 Locally

  1. Download the code here and unzip the file anywhere on your file system, or clone this repository.
  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.

Deploying to Heroku

  1. If you don’t have a Heroku account, follow these instructions to create an account, install the Heroku toolbelt, and login
  2. In Terminal (Mac), or a Command Window (Windows), clone the soql-explorer repository:
    git clone https://github.com/ccoenraets/soql-explorer
    
  3. Navigate to the sql-explorer folder:
    cd sql-explorer
    
  4. Create a Heroku app:
    heroku apps:create
    
  5. Take note of the application name that Heroku gave to your app. For example, murmuring-waters-3927. Use the actual name of your app in the instructions below.
  6. In Salesforce, create a Connected App as described in the local instructions above. For the Callback URL, make sure you use https and your Heroku app name. For example: https://murmuring-waters-3927.herokuapp.com/oauthcallback.html
  7. Modify app.js and specify your connected app clientId and connection URLs matching your Heroku app name. For example:
    • redirectURI: https://murmuring-waters-3927.herokuapp.com/oauthcallback.html
    • proxyURL: For example: https://murmuring-waters-3927.herokuapp.com/proxy
  8. Commit your changes and push your app to Heroku:
    git add . --all
    git commit -m 'Changed app parameters'
    git push heroku master
    
  9. Open the application in a browser (make sure you use https):
    
    https://murmuring-waters-3927.herokuapp.com
    
    
  10. Click the Login button (upper right corner) and enter your Salesforce credentials
  11. 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.

14 Responses to Salesforce SOQL 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

  7. Viroshi May 7, 2014 at 4:57 pm #

    Hi,

    Thanks for the post.

    Would be glad, if you can describe a bit more on how to use node.js as a proxy..

    Also, I am using force.com site to host my pages(login and oauthcallback) and I am confused how and what to use the proxyurl..!

    Can you please guide me through these….?

    - Viroshi

  8. Viroshi May 8, 2014 at 6:33 am #

    I got it. I did not read the given documentation properly. After reading the above given info clearly, it solved all my issues.

    Thanks a ton!!!!!!!

  9. Radhika May 8, 2014 at 7:03 am #

    Hi,

    Thanks for the post. It helped me greatly.

    Can you please share the method that can be used for inserting data into salesforce? I tried but it was not being inserted.

    Thanks in advance

    Yours,
    Radhika

  10. Arup Sarkar July 7, 2014 at 11:30 pm #

    Hi Christophe,

    I deployed it in heroku, changed everything that you mentioned, when I am clicking on Login, the oAuth pop up is coming up, when I am clciking Allow, I am getting a blank page, I am getting the following in error console.

    Error Start:
    ===============
    TypeError: ‘undefined’ is not a function (evaluating ‘window.opener.oauthCallback(response)’)
    global code
    ===============

    I downloaded the code from your site. In your example above you have “loginDialogCallback” but in github you have “oauthCallback”

  11. Arup Sarkar July 8, 2014 at 1:29 am #

    This is the error I am getting in console.

    Blocked a frame with origin “https://cryptic-forest-6046.herokuapp.com” from accessing a frame with origin “http://cryptic-forest-6046.herokuapp.com”. The frame requesting access has a protocol of “https”, the frame being accessed has a protocol of “http”. Protocols must match.

    I have https in Callback URL of connected App in SFDC and everywhere I have https:// in app.js

    • Arup Sarkar July 8, 2014 at 1:34 am #

      The above error is gone when I am accessing the heroku app using https:// but the original error is still showing.

  12. Arup Sarkar July 8, 2014 at 7:59 am #

    I do not have require(‘http’) and require(‘request’) which helps to by pass browser’s cross origin restrictions. I will make changes to my server.js and post that should solve it.

  13. Arup Sarkar July 8, 2014 at 11:54 pm #

    Resolved,
    Problem : I was already using anonymous function block in app.js. From oauthcallback.html I was not able to call the oauthCallback function (it was not visible). I declared the function as a variable outside the anonymous block and then defined the body inside, which worked.

    var oauthCallback;

    (function(){

    oauthCallback = function(response){

    }

    }());

Leave a Reply

css.php