Saturday, January 29, 2011

Salesforce REST API Update and Delete Record

So far we have looked at how to create and read records from Salesforce using the REST API, so the final two basic operations we need are Update and Delete.

Update

The code for doing an update is almost identical to the code for doing an insert with just two small differences.
First we need to specify the ID of the record we want to update in the URI just like we did for a read:

var uri = instanceURL + "/services/data/v20.0/sobjects/Account/0017000000hX4Iz";

Second we will use PATCH for the HTTP method instead of POST. Not that PATCH isn’t a standard HTTP method, but fortunately the .NET WebRequest class allows for arbitrary methods.
Just like with an insert you put the JSON or XML encoded object into the body of the request. You can put all the fields in the body or just the ones you want to update.  If you decide to use XML for the body don’t forget to change the ContentType from JSON to XML:

req.ContentType = "application/xml";

The only other difference with an update is the response. Unlike the other function we have looked at so far, the content of the response will be empty if the update succeeds.


Delete

Delete is probably the simplest operation. We use the same URI as an update, one that contains the id of the record we want to delete, and set the HTTP method to DELETE. Nothing needs to be put in the body of the request for a delete. Just like an update, if the delete is successful the response will be empty.

Sunday, January 16, 2011

Salesforce REST API Read Record

In my last post I showed how to create a new record in Salesforce using the REST API, now lets look at reading a record.
To access a record you need to add the record’s id to the end of the object URI that I showed in the last post. For example to access a specific account record you would use:
http://na1.salesforce.com/services/data/v20.0/sobjects/Account/001D000000INjVe
The id’s aren’t shown directly when you edit a record in SFDC, but you can find the record id in the URL when you are editing a record. You can also get an id from the response when you create a record as we saw last time.
The code to perform the read will look something like this:

public string ReadData()
{
var uri = instanceURL + "/services/data/v20.0/sobjects/Account/0017000000hX4Iz";

var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
req.Headers.Add("Authorization: OAuth " + accessToken);
req.Headers.Add("X-PrettyPrint:1");
req.ContentType = "application/json";
req.Method = "GET";

WebResponse resp;

try
{
resp = req.GetResponse();
}
catch (WebException ex)
{
resp = ex.Response;
}

var sr = new System.IO.StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();
}

This is pretty much the same code we used for the insert but it uses an HTTP GET instead of POST,  and there is no body needed for the request. You will also notice a new header, X-PrettyPrint:1. This will make SFDC return the response in a more readable format with appropriate line breaks and indentation. This header can be used in any of the REST API commands.

The response will contain the JSON formatted Account object. Remember, as always, you can add .xml to the end the URI to have the response returned in XML instead of JSON.

By default this command will return all the fields in the record. You can specify only the fields you want to return like this:

http://na1.salesforce.com/services/data/v20.0/sobjects/Account/001D000000INjVe?fields=AccountNumber,Name

We have added a query string called fields to the URI which lists the fields you want to return.

Saturday, January 8, 2011

Salesforce REST API Record Creation

In my last few articles I showed the basics of how to connect to Salesforce using the REST API and how to use some basic functions. Now lets look at how to actually manipulate the data stored in SFDC. We will start by looking at how to insert a new record.
When you are working with tables (called objects in the SFDC nomenclature), the URI will look something like this:
http://na1.salesforce.com/services/data/v20.0/sobjects/Account/

  • http://na1.salesforce.com  is the instance URL that you get during the login process.
  • /services/data/v20.0/ indicates the version of SFDC you will be using.
  • sobjects/ is the resource we will be accessing, in this case the SFDC objects (tables).
  • Account/ is the name of the object we will be creating the new record in.
To insert a new record we will do an HTTP POST to this URI. In the headers we will pass the authorization token, and in the body we will pass the JSON encoded data we want to insert. For example here is a simple piece of JSON that will insert a new Account with the name TestAccount and number 1234567.
{    
"Name" : "TestAccount",
"AccountNumber" : "1234567"
}

Now lets look at the C# code to perform this insert. First, to simplify the creation of our JSON lets create an Account class that we can serialize.

public class sfdcAccount
{
public string Name { get; set; }
public string AccountNumber { get; set; }

}

Next we will setup our URI and the account object

var uri = instanceURL + "/services/data/v20.0/sobjects/Account/";

var acct = new sfdcAccount();
acct.Name = "NewAccount";
acct.AccountNumber = "123456";

and then serialize the account object into JSON.

var ser = new JavaScriptSerializer();
var body = ser.Serialize(acct);

We can now create our HTTP request.

var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
req.Headers.Add("Authorization: OAuth " + accessToken);
req.ContentType = "application/json";
req.Method = "POST";


Here we create an HttpWebRequest object pointing to the URI we specified earlier. We then set a header that contains the access token we got during the login process, set the content type to JSON and finally specify that this is an HTTP POST request.

Next we need to add the body of the request. This code will convert our JSON to a byte array an attach it to the request.

byte[] data = System.Text.Encoding.ASCII.GetBytes(body);
req.ContentLength = body.Length;
var os = req.GetRequestStream();
os.Write(data, 0, data.Length);
os.Close();

Finally we execute the request and retrieve the result that SFDC sends back.

WebResponse resp;

try
{
resp = req.GetResponse();
}
catch (WebException ex)
{
resp = ex.Response;
}

if (resp == null) return null;
System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();

The try/catch around the request is important. When there is an error executing the command SFDC will return a HTTP response code of 400 which will throw an exception. To resolve this problem we catch the exception and retrieve the response object from the exception.

Assuming there are no errors, SFDC will return a JSON response that looks like this

{
"id":"0017000000hX4BIAA0",
"errors":[],
"success":true
}

First we get back the internal id of the record that was created. We can use this later to read, update, or delete this record. We also get back a true/false field indicating the success or failure of the insert and an errors field. I have not yet found a case where these are used since an error will return a different response. For example if we make the AccountNumber greater the 40 characters we will get the following response:

{
"fields":["AccountNumber"],
"message":"Account Number: data value too large: 1234567890123456789012345678901234567890123456789012345678901 (max length=40)",
"errorCode":"STRING_TOO_LONG"
}