8

The SOAP API has an explicit undelete() call to restore deleted records from the recycle bin.

Is there an equivalent resource for the REST API to undelete records? I see ways to find records that are deleted, but I can't find a way to reverse the process.

9

It can't. Here are the HTTP verbs:

  • HEAD (retrieve resource metadata)
  • GET (retrieve information, such as basic resource summary information)
  • POST (create a new object)
  • PATCH (update a record)
  • DELETE (delete a record)

The undelete verb is conspicuously missing ;-) and there are zero occurrences of 'undelete' in 192 pages of documentation.

Force.com REST API Developer Guide

https://resources.docs.salesforce.com/sfdc/pdf/api_rest.pdf

On a whim, tried patching the IsDeleted flag on a deleted record. But to no avail:

> PATCH /services/data/v36.0/sobjects/Account/00158000004AWnF HTTP/1.1
> Content-Type: application/json
> {"IsDeleted":false}

< HTTP/1.1 404 Not Found
< Content-Type: application/json;charset=UTF-8
< [{"message":"entity is deleted","errorCode":"ENTITY_IS_DELETED","fields":[]}]

Same goes for posting with the Id of the deleted record specified:

> POST /services/data/v36.0/sobjects/Account/ HTTP/1.1
> Content-Type: application/json
> {"Id":"00158000004AWnF","IsDeleted":false}

< HTTP/1.1 400 Bad Request
< Content-Type: application/json;charset=UTF-8
< [{"message":"The Id field should not be specified in the sobject data.","errorCode":"INVALID_FIELD"}]
  • 5
    I appreciate that the appeal of a REST API is how it aligns with the HTTP verbs. Still, to just ignore functionality that doesn't fit nicely seems like a bit of a gap. Patching the IsDeleted field seems like it would have been reasonable. – Daniel Ballinger Apr 10 '16 at 21:41
  • 4
    I've posted the idea: Add the equivalent of the SOAP API undelete() call to the REST API.. Also, my kingdom to be able to fix dumb spelling/grammar mistakes in Salesforce idea and forum posts. – Daniel Ballinger Apr 10 '16 at 21:47
4

There is no undelete REST API natively built in .

All is not lost and one can always write a bit of apex to accomplish this functionality

//Execute Anonymous

Account a = new Account(Name='Trump');
insert(a);
insert(new Contact(LastName='Carter',AccountId=a.Id));
delete a;

//REST API to Undelete

@RestResource(urlMapping='/AccountUndelete/*')

 global with sharing class UndeleteRestResource {
   @HttpGet
  global static list<Account> doGet() {
     RestRequest req = RestContext.request;
     RestResponse res = RestContext.response;
     String accountname = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
     Account[] restoredAccts = [SELECT Id, Name FROM Account WHERE Name = :accountname  ALL ROWS]; 
     try {
        undelete restoredAccts ;
     } catch (DmlException e) {
     // Process exception here
     }
     return restoredAccts ;
   }
}
  • 2
    Rolling our own does seem like a good backup solution. – Daniel Ballinger Apr 10 '16 at 21:44
  • 3
    It's better than having nothing :) – Mohith Shrivastava Apr 10 '16 at 21:44
2

The HTTP verbs provide the base building blocks from which any more complex behaviour can be constructed by representing the life cycle of a "thing" (it can be created, its state can be ascertained, its state can be changed and it can be destroyed). The HTTP verbs POST, GET, PUT, DELETE respectively provide the methods to manage that life cycle.

Once a thing has been DELETED its life cycle has ended. But you seem to be treating "deleted" things as still engaged in a life cycle (ie they can be returned to a previous state). What you are talking about is not really the deletion and recreated from non-existence of a record but merely the transition of a record from state to state. In this case an active to an inactive state, and back again (presumably through some kind of archiving mechanism). Transition between these states can be handled with a PUT to the resource in question (or POST for transition of groups of resource instances).

If you don't want to have to go through and update your queries to ignore accounts with an inactive state you could actually have the resource move the raw data to an archive data store of some kind and out of the regular datastore (and back in if the account transitions back to an active state at a later date).

  • Salesforce currently uses the DELETE verb to delete a record. Once in that state it remains in the Recycle Bin for a period of time. Both the SOAP API and the web UI provide the ability to restore any record that is undeletable. Perhaps they should PUT records into a recycling state rather than DELETE them initially, but I can't see that changing in the near future. – Daniel Ballinger Apr 11 '16 at 9:35
  • Yep that's the way they should do it. – GDT_Tony Apr 12 '16 at 1:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.