Saturday, November 9, 2013

Salesforce Get Deleted/Get Updated

Salesforce has just started releasing the Winter ’14 update which contain a couple new features in the REST API. You can view the full release notes here:

https://help.salesforce.com/help/doc/en/salesforce_winter14_release_notes.pdf

In this post I want to talk about the new Get Deleted and Get Update resources. As the names suggest these resources are used to retrieve lists of recently deleted and update records. These are specifically designed to facilitate replication of data. For example, if you are developing a mobile app you may want to store a local copy of some of the contact fields. These resources will help you keep that local copy in sync.

Get Deleted

First, let’s look at Get Deleted. The URI for this resource looks like this:

/services/data/v29.0/sobjects/Contacts/deleted/
?start=2013-05-05T00:00:00+00:00&end=2013-05-10T00:00:00+00:00

This will return a list of all Contacts that were deleted between the specified start and end dates.
There are a couple things you need to be careful of when specifying the dates. First, the dates are UTC not local time, second they must be in ISO 8601 format and third the start date has to been within 30 days of the current date.

Let’s talk a little more about how to format the dates. If you want to send the date in the “2013-05-05T00:00:00+00:00” format you must UrlEncode it because of the plus sign. This can be done in .NET like this:

System.Web.HttpUtility.UrlEncode(“2013-05-05T00:00:00+00:00”)

Note that you may need to add a reference to the System.Web assembly if you are developing a desktop application. It turns out that there is no simple way to generate this format date in .NET short of using a custom format string. As an alternative you can use a slight variation of this format, "2013-10-08T04:00:00Z". There is a standard format that come pretty close to this but puts a space between the time and date instead of the ‘T’, but this can easily be fixed. Here is an example of how to convert a DateTime variable in local time to the properly formatted UTC time:

dtStart.ToUniversalTime().ToString("u").Replace(" ","T");

When you make the Get Deleted call you will get a JSON result that looks like this:

{
  "deletedRecords" : [ {
    "id" : "003E000000kkhvtIAA",
    "deletedDate" : "2013-10-09T12:17:12.000+0000"
  }, {
    "id" : "003E000000kle9zIAA",
    "deletedDate" : "2013-10-09T19:03:28.000+0000"
  }, {
    "id" : "003E000000kmVqiIAE",
    "deletedDate" : "2013-10-11T11:46:00.000+0000"
  } ],
  "earliestDateAvailable" : "2012-10-28T16:00:00.000+0000",
  "latestDateCovered" : "2013-10-11T12:05:00.000+0000"
}


you will see an array called deletedRecords which contains the id of the deleted record and the date it was delete, again in UTC. In a synchronization scenario you would use these id’s to delete the records from the local copy. The lastDateCovered value is the last date that the query looked at for deleted records. You would save this value and use it as the start date for you next Get Delete query. The API documentation says that earliestDateAvailable is “timestamp (Coordinated Universal Time (UTC)—not local— timezone) of the last physically deleted object.”, although I haven’t been able to figure out what that really means.


Get Updated

Get updated works like Get Deleted, but returns a list of the ID’s of objects that were either added or modified between the specified dates. The URI for this resource looks like this:

/services/data/v29.0/sobjects/Contacts/updated/?start=2013-05-05T00:00:00+00:00&end=2013-05-10T00:00:00+00:00

All the rules for dates are the same as they are for Get Deleted. When you make a Get Updated call you will get back a JSON result that looks like this:


{
  "ids" : [ "003E000000QCZ1kIAH", "003E0000001ZufeIAC", "003E000000kmVoiIAE" ],
  "latestDateCovered" : "2013-10-21T10:59:00.000+0000"
}


The ids array contains the id of each object that was either added of modified. Just like with Get Deleted, lastestDateCovered is the last date that the query looked at for updated records. You would save this value and use it as the start date for you next Get Updated query