Wednesday, June 8, 2011

Using Salesforce.com's REST API from Perl

Introduction

Here's a simple way to access Salesforce data even from behind a firewall, using Perl and the REST API.

If you're not familiar with the details of the Salesforce REST API, have a look at the developer docs.

I'm using Perl 5.12.1 with modules WWW::Mechanize, and WWW::Salesforce.

The firewall settings (optional)

Since I'm behind a firewall, I have to define the necessary variables so the various Perl packages can route the requests properly.  Here's what's needed:
 #!/usr/bin/perl
use warnings;
use strict;
use WWW::Mechanize;
use WWW::Salesforce;

# The firewall proxy variables:
$ENV{HTTPS_PROXY} = 'http://proxy.org.com:80';
$ENV{HTTPS_PROXY_USERNAME} = "proxy_user";
$ENV{HTTPS_PROXY_PASSWORD} = "proxy_pass";
my $mech = WWW::Mechanize->new();
$mech->agent('Mozilla/5.0');
$mech->proxy('http', 'http://proxy_user:proxy_pass@proxy.org.com:80');
$mech->proxy('https', undef);

If you don't need to go through a firewall, you can skip all of these proxy settings, but you'll still need the $mech definition, as it will be used to make the REST requests later.

Authorization

The most difficult part (and it wasn't difficult) was setting up the authorization.  Salesforce offers two options:
  1. OAuth 2.0
  2. Session ID
The Sesion ID is far easier than the first option, so I'm using it here.

The first step is to log-in via the SOAP API (since that is a way to get a session ID):

# Authenticate first via SOAP interface to get a session ID:
my $sforce = eval { WWW::Salesforce->login(
                    username => 'sfdc_user@org.com',
                    password => 'sfdc_pass' ); };
die "Could not login to SFDC: $@" if $@;

Session ID

Now that we've logged-in via the SOAP API, we have a session ID as part of the $sforce variable, which we can get as follows:
 # Get the session ID:
my $hdr = $sforce->get_session_header();
my $sid = ${$hdr->{_value}->[0]}->{_value}->[0];

This SID will need to be sent as part of our request header when using the REST API.

A REST Request

Here's a simple request for all available SObjects:
# Now get some data (using the session ID from above):
$mech->add_header( "Authorization" => "OAuth $sid" );
$mech->add_header( "X-PrettyPrint" => '1' );
$mech->get("https://na1.salesforce.com/services/data/v20.0/sobjects/
");
# ...and write it out to the screen:
print $mech->content;

Going further

 The developer doc mentioned above lists lots of examples for requests that can be made this way, including SOQL queries.