Hello Trailblazers,
Welcome to the 4th tutorial in the Salesforce Integration Tutorial Series. In the previous tutorial we learned about the POST method in detail. You can have a look at the same by clicking here. In this tutorial, we'll be working with the DELETE method, creating a custom REST API and will be working with Contact object which is already present in Salesforce.
The DELETE method in HTTP is mainly used to delete one or more records. We'll modify our existing code and have a look at the deletion of records using the method with @HTTPDelete annotation. The delete request usually don't have a request body and receive the parameters in the URL itself. In most cases, we pass the record id in the URL and that record id is used to delete the record in the system.
To begin, let's have a look at the below code:-
As you can see above, In my ContactResource class, I have updated the method name to deleteContact which is returning a Map<String, String> in the response and is having an annotation of @HTTPDelete. Inside this method, I have initialized a Map<String, String> which has a name responseMap. After that, I have initialized my RestRequest instance named contactRequest with the request context variable of RestContext class. Therefore, I have my actual request now assigned to the contactRequest variable.
As, I am deleting the contact here, I'll be adding a contact id to the end of the URL. The contact id will be used to delete the respective contact. So, next I am getting the requestURI from the contactRequest and then getting the Id of the contact by getting the substring after the last slash (/) in the URI and converting it to the Id format by passing it into Id.valueOf() method. Now, as I got the contact id of the contact to delete. I am initializing a new Contact with this id.
At the end, I have a try-catch block. In the try block, I am trying to delete the contact. If the contact is deleted, I am adding two key-value pairs in the responseMap i.e. success with value 1 and message with value Record Deleted Successfully. In case of an exception, I am capturing the DmlException in the catch block. In that case, I am again adding two key-value pairs in the responseMap but here success will have a value 0 and message will have a value ex.getMessage() which will return the error message from the exception as a string, as ex is the instance of our DmlException class. Finally, I am returning the responseMap in the response.
I tried calling this API from workbench by passing a valid contact id and got the response below:-
As you can see above, I have selected DELETE from the radio buttons and passed the contact id of the contact I wanted to delete and I am getting the proper response with a success value of 1 and message value as:- Record Deleted Successfully. Now, if I try to call the same API with the same input again, I am getting the below response:-
As you can see above, this time, I am having a success value as 0 and message consits of the actual error message. You can see that this is a DML exception as I am trying to delete a record which is already deleted. You can also have a look at the raw response which will be in the proper JSON format as shown below:-
Welcome to the 4th tutorial in the Salesforce Integration Tutorial Series. In the previous tutorial we learned about the POST method in detail. You can have a look at the same by clicking here. In this tutorial, we'll be working with the DELETE method, creating a custom REST API and will be working with Contact object which is already present in Salesforce.
The DELETE method in HTTP is mainly used to delete one or more records. We'll modify our existing code and have a look at the deletion of records using the method with @HTTPDelete annotation. The delete request usually don't have a request body and receive the parameters in the URL itself. In most cases, we pass the record id in the URL and that record id is used to delete the record in the system.
To begin, let's have a look at the below code:-
As you can see above, In my ContactResource class, I have updated the method name to deleteContact which is returning a Map<String, String> in the response and is having an annotation of @HTTPDelete. Inside this method, I have initialized a Map<String, String> which has a name responseMap. After that, I have initialized my RestRequest instance named contactRequest with the request context variable of RestContext class. Therefore, I have my actual request now assigned to the contactRequest variable.
As, I am deleting the contact here, I'll be adding a contact id to the end of the URL. The contact id will be used to delete the respective contact. So, next I am getting the requestURI from the contactRequest and then getting the Id of the contact by getting the substring after the last slash (/) in the URI and converting it to the Id format by passing it into Id.valueOf() method. Now, as I got the contact id of the contact to delete. I am initializing a new Contact with this id.
At the end, I have a try-catch block. In the try block, I am trying to delete the contact. If the contact is deleted, I am adding two key-value pairs in the responseMap i.e. success with value 1 and message with value Record Deleted Successfully. In case of an exception, I am capturing the DmlException in the catch block. In that case, I am again adding two key-value pairs in the responseMap but here success will have a value 0 and message will have a value ex.getMessage() which will return the error message from the exception as a string, as ex is the instance of our DmlException class. Finally, I am returning the responseMap in the response.
I tried calling this API from workbench by passing a valid contact id and got the response below:-
As you can see above, I have selected DELETE from the radio buttons and passed the contact id of the contact I wanted to delete and I am getting the proper response with a success value of 1 and message value as:- Record Deleted Successfully. Now, if I try to call the same API with the same input again, I am getting the below response:-
As you can see above, this time, I am having a success value as 0 and message consits of the actual error message. You can see that this is a DML exception as I am trying to delete a record which is already deleted. You can also have a look at the raw response which will be in the proper JSON format as shown below:-
What if I want to delete multiple records ?
In this case, either you can use URL parameters about which we have learned earlier in the GET method tutorial. You can view that tutorial by clicking here. However, I am going to use the same approach as we're already using and I am going to add comma , separated contact ids at the end of the URL like:- /services/apexrest/ContactAPI1/0037F00001hw4nG,0037F00001hw5lB,.....
Let's have a look at the below code of ContactResource1 class having the urlMapping as:- /ContactAPI1/*
As you can see above, this time I have created a new wrapper class with a global identifier named as ResponseWrapper which has two String variables:- success and message. After that, I have created an @HTTPDelete method named as deleteContacts which will return the list of my ResponseWrapper in the response. I'll get the list of ResponseWrapper in response and I'll be able to check for each contact, whether it was deleted or not.
In this method, first I've initialized a List<ResponseWrapper> named responseWrapperList. I have again got the contactRequest and the contactRequestURI same as previous but this time, I am splitting the substring after slash (/) from the URI using a comma (,) and getting the array of contactIds in return. So, my URL will be like:- /services/apexrest/ContactAPI1/0037F00001hw4nG,0037F00001hw5lB,.... I can have multiple contact ids of the contacts I want to delete after the ending /. I'll take that substring and split it using a , and I'll get the contact ids in a string array named contactIds. After that, I have initialized a new list of contact named contactsToDelete and I have a for loop running over my contact ids inside which I am creating an instance of contact for each id and adding it to the contactsToDelete list.
Now, I want to make partial deletion possible, i.e. if I am sending 10 contacts for deletion and 5 can be deleted while 5 cannot, salesforce will delete those 5 which can be deleted easily. For this, I am using the Database.delete() method which is taking the list of contacts to delete as the first parameter and it's second parameter represents allOrNone which is a boolean variable. If allOrNone is true, either all the contacts will be deleted or none of them. On the other hand, if allOrNone is false, deletion of some contacts in the list is possible even when others cannot be deleted. The Database.delete() returns an array of Database.DeleteResult which is named as:- deleteResults which can tell us the status of the delete operation for every contact.
At last, I am iterating these deleteResults and for each iteration, I am creating a new instance of ResponseWrapper by the name wrapper. Then I am checking for each contact whether the operation was successful by isSuccess() method. If the operation was successful, I am setting up the success and message variables in the wrapper for that contact with appropriate values and in case, the operation was not successful, I am getting the errors using deleteResult.getErrors() which will return a list of Database.Error class that I am iterating in a for loop by assigning one instance of Database.Error at a time by the name error. I am forming the proper error message using methods from the Database.Error class like:- getStatusCode(), getMessage() and getFields(). Finally, I am adding this wrapper to the responseWrapperList and returning this list as a response.
I tested this API in workbench with one valid contact id and another id of a contact which was already deleted. I got the below response:-
As you can see above, I was able to delete one contact while other contact cannot be deleted as the id was not valid. I got two different responses in a list which was returned to me in the response. If you check the raw response, it'll show you the proper JSON format as below:-
That's all for this tutorial. In the next tutorial, we'll explore the PUT method in detail.The whole code of this tutorial is available in the delete branch of my SFDC-Integration-Tutorial github repository which can be viewed by clicking here.
Tired of reading or just scrolled down, don't worry, you can watch the video too.
If you liked this tutorial, make sure to share it in your network and let me know your feedback in the comments section below.
Happy Trailblazing..!!
In this method, first I've initialized a List<ResponseWrapper> named responseWrapperList. I have again got the contactRequest and the contactRequestURI same as previous but this time, I am splitting the substring after slash (/) from the URI using a comma (,) and getting the array of contactIds in return. So, my URL will be like:- /services/apexrest/ContactAPI1/0037F00001hw4nG,0037F00001hw5lB,.... I can have multiple contact ids of the contacts I want to delete after the ending /. I'll take that substring and split it using a , and I'll get the contact ids in a string array named contactIds. After that, I have initialized a new list of contact named contactsToDelete and I have a for loop running over my contact ids inside which I am creating an instance of contact for each id and adding it to the contactsToDelete list.
Now, I want to make partial deletion possible, i.e. if I am sending 10 contacts for deletion and 5 can be deleted while 5 cannot, salesforce will delete those 5 which can be deleted easily. For this, I am using the Database.delete() method which is taking the list of contacts to delete as the first parameter and it's second parameter represents allOrNone which is a boolean variable. If allOrNone is true, either all the contacts will be deleted or none of them. On the other hand, if allOrNone is false, deletion of some contacts in the list is possible even when others cannot be deleted. The Database.delete() returns an array of Database.DeleteResult which is named as:- deleteResults which can tell us the status of the delete operation for every contact.
At last, I am iterating these deleteResults and for each iteration, I am creating a new instance of ResponseWrapper by the name wrapper. Then I am checking for each contact whether the operation was successful by isSuccess() method. If the operation was successful, I am setting up the success and message variables in the wrapper for that contact with appropriate values and in case, the operation was not successful, I am getting the errors using deleteResult.getErrors() which will return a list of Database.Error class that I am iterating in a for loop by assigning one instance of Database.Error at a time by the name error. I am forming the proper error message using methods from the Database.Error class like:- getStatusCode(), getMessage() and getFields(). Finally, I am adding this wrapper to the responseWrapperList and returning this list as a response.
I tested this API in workbench with one valid contact id and another id of a contact which was already deleted. I got the below response:-
As you can see above, I was able to delete one contact while other contact cannot be deleted as the id was not valid. I got two different responses in a list which was returned to me in the response. If you check the raw response, it'll show you the proper JSON format as below:-
That's all for this tutorial. In the next tutorial, we'll explore the PUT method in detail.The whole code of this tutorial is available in the delete branch of my SFDC-Integration-Tutorial github repository which can be viewed by clicking here.
Tired of reading or just scrolled down, don't worry, you can watch the video too.
If you liked this tutorial, make sure to share it in your network and let me know your feedback in the comments section below.
Happy Trailblazing..!!
Tanks Man
ReplyDeleteYou're always welcome :-)
DeleteThank you so much for sharing details of your code. Actually that helps a lot in learning new stuff. Like from above I got an idea of storing all debugs for so many different fields in a map and just look for that map while watching debug to catch the error fast. You are genius and best part is that you actually using the Salesforce APIs to nurture your coding style and share all your efforts too !! keep it up , and just can say that you are doing a great job!! You really mean it that sharing is caring!!
ReplyDeletecan you help me i am facing this Error:-System.StringException: Invalid id: ContactAPI Class.ContactResource.DelContact: line 28, column 1
ReplyDeleteLine no 28 is:-
Id contactId = Id.valueOf(contactRequestURI.substring(contactRequestURI.lastIndexOf('/') + 1));
It looks like you're not passing the correct record id, please make sure you're passing a valid id.
DeleteVery knowledgeable posts
ReplyDelete