#Salesforce cloud #integration using APEX #REST #API and testing it
Salesforce REST Web Services API will expose the organization data to external applications.
REST uses simple HTTP methods like GET, POST, PUT, DELETE, PATCH and HEAD to access and manipulate data. The data exchange format is in the form of JSON generally as JSON is faster than xml format.
1. The following is a sample apex class which illustrates the GET method to retrieve details from an external application
/*
urlMapping acts as an accessible endpoint & adds to full URL used to call this webservice externally
For example, something like "https://ap1.salesforce.com/services/apexrest/showStudentDetails"
An ashtrick in showStudentDetails/*' means to work on all the records under it
*/
@RestResource(urlMapping='/showStudentDetails/*')
// Global class is used because this class should be accessible outside salesforce
global class checkStudent
{
// Get methods can be used from outside to fetch any data from salesforce
@HttpGet
//Return type used is LIST as we will return more than one record to outside of salesforce
global static LIST<Student__c> getStudent()
{
//create empty list to hold all the records to send out
LIST<Student__c> studentList;
//try and catch will be very handy when it comes to analyze issues if the code written doesn't work
try
{
// The SOQL query written using 'select' returns all the records in students object/table
studentList = [select name from Student__c];
return studentList;
}
catch (Exception err)
{
//log the error happened with its related message in debug logs
system.debug('Error'+err.getMessage());
}
// This statement should be added to avoid compile error (not returning anything but in function
// definition its expecting a return List return type even though we have one in try block
return studentList;
}
}
To verify the APEX Rest class created, we can use salesforce workbench tool.
Get the API version of developer Org before logging in to workbench version so that both developer org, workbench are matching and doesn’t cause problem in using different features between versions.
Note: To know the version open any of the APEX class and go to ‘Version Settings’ as shown in pic below
URL for workbench: https://workbench.developerforce.com/login.php
Note: If already login in developer Org of salesforce then here it directly takes inside without asking credentials
Note: No need to select any object after selecting ‘REST Explorer’ in Workbench
Edit the execute path to “/services/apexrest/showStudentDetails”. Press ‘Execute’ button to get all the records if it works without error.
Note: Re-call that we gave URL mapping as ‘showStudentDetails’ for REST class. So this URL mapping is responsible to call the GET function @HttpGet (as we selected radio button as GET in work bench)
We can expand the folders to see all the record contents that was result from the SOQL query in APEX class. Also clicking on ‘Show Raw Response’ gives the JSON format (key and value pair) of the data retrieved from salesforce Org.
Hope you got an idea of how to get the data from REST API and how its output looks like.
Note: Authentication is not required here because the workbench login was done using salesforce login. As both are using same access, no authentication required from workbench. However if the same call is done in Java or other external applications then OAuth Settings has to be set in Salesforce.
What are the advantage of using REST over other web services?
REST has more control on what all fields that are required and also has control on what records to be allowed or accessed at a time. Whereas other web services get all the records and all fields each time.
In the above APEX REST class under try block add LIMIT like below highlighted and try save, ‘Execute’ on work bench with same URI. This will results in fetching only first 3 records only.
studentList = [select name from Student__c LIMIT 3];
2. What if I need to fetch a specific record using REST API?
Yes this can be also achievable in REST service. The above method gives all the records or first few records. The URI (used to send a REST request for fetching records) can be further used to query the specific data by upending additional details in it.
URI: ‘/services/apexrest/showStudentDetails’
Extra notes: Now what is URI? URL (Uniform Resource Locator) like we mostly used in web browser window is a subset of URIs that, in addition to identifying a resource, provide a means of locating the resource by describing its primary access mechanism (e.g. its network ‘location’).
@RestResource(urlMapping='/showSpecificStudentDetails/*')
// Global class is used because this class should be accessible outside salesforce
global class checkSpecificStudent
{
// Get methods can be used from outside to fetch any data from salesforce
@HttpGet
//Return type used is Object name as we will return only one specific record to outside of salesforce
global static Student__c getSpecificStudent()
{
//create an empty variables of REST request and response types
RestResponse studentRes = RestContext.response;
RestRequest studentReq = RestContext.request;
//Collect the URI, get only the request ID upended and store it to a string variable
String studentID = studentReq.requestURI.substring(studentReq.requestURI.lastIndexOf('/')+1);
System.debug('Student ID ='+studentID);
//Query from the captured URI ID. Get only specific fields required
//Make sure : binding is added as its a varible and not a actual number
Student__c result=[SELECT Id, name from Student__c WHERE Id=:studentID];
return result;
}
}
To invoke this web service from work bench, we have to upend the record ID in URI which we want to specifically looking for. To collect the record ID, open Student record and on the browser collect the 15 digit ID on the URL at the end.
Now on the workbench modify the URI by appending the record ID to it as shown below and ‘Execute’
URI: /services/apexrest/showSpecificStudentDetails/a004100000FqRoH
Note:
1) The Record ID copied and sent in URI was of 15 digit and in the result it is shown as 18 digit with ‘AAV’ appending to it is the external ID with 3 digit CRC added to it.
2) It fetched specific record with specific field requested only. Even thought it had other fields ‘Last Name’ and ‘Gender’, it displayed only ‘Student Name’ field name.
3. How to use REST services to add records inside Salesforce from external applications?
We can create REST API to collect the data from external applications using HTTP POST method and use the DML or database methods to insert the records to salesforce org.
@RestResource(urlMapping='/addStudentDetails/*')
// Global class is used because this class should be accessible outside salesforce
global class addStudent
{
// Post methods can be used from outside to added any data to salesforce
@HttpPost
//Return type used is String as we will return record ID created successfully to outside of salesforce
global static String addStudent(String name, String lastName)
{
//create an empty instance of Student__c type
Student__c student = new Student__c();
//Fill the members or feilds with the request coming from outside salesforce
student.name = name;
student.Last_Name__c = lastName;
//Perform a DML insert operation to add the record in salesforce as per the request got externally
insert student;
return student.id;
}
}
URI: /services/apexrest/addStudentDetails
In workbench, Select ‘POST’ radio button and write ‘Request body’ in JSON format (Key : Value) pair with a comma separated between each pair. Click ‘Execute’.
Troubleshooting: If there is a JSON phrase error then
- check if you have given the parameter name used in the REST member function in APEX class and not the field API name
- check if you have added a comma operator between each (key : Value) pairs
The return value is the record ID which was newly created after DML operation as mentioned in the REST API. We can also do database methods similar to DML operations too which has more flexibility and control over the insert operations.
Check the Student record added from outside salesforce is added to the table/object Student in Students tab.
4. How to use REST API services to delete existing records?
We can use similar operations as Get method and get the records to be deleted and then do a delete DML operation on it from outside salesforce platform. Here is the REST class for delete operation.
@RestResource(urlMapping='/deleteStudentDetails/*')
// Global class is used because this class should be accessible outside salesforce
global class deleteStudent
{
// Delete methods can be used from outside to delete any data in salesforce
@HttpDelete
//Return type used is void as we will not return anything after delete
global static void deleteStudent()
{
//create a empty variables of REST request and response types
RestResponse studentRes = RestContext.response;
RestRequest studentReq = RestContext.request;
//Collect the URI, get only the request ID and store it to a string variable
String studentID = studentReq.requestURI.substring(studentReq.requestURI.lastIndexOf('/')+1);
System.debug('Student ID ='+studentID);
// Query from the captured URI ID.
// Make sure : binding is added as its a varible and not a actual number
Student__c student=[SELECT Id, name from Student__c WHERE Id=:studentID];
delete student;
}
}
To Execute this we need to collect the record ID from the existing one and also see all the fields which are available in that record as highlighted in snapshot below
In work bench, provide the URI with record ID appended at the end as show below and press Execute by selecting DELETE radio button.
After DELETE operation check the recycle bin to confirm the record deletion. Here we can restore it (Undelete) or delete it from recycle bin manually by using the buttons as shown in snapshot. After 15 days this record will be automatically deleted by salesforce.
If you have learned or enjoyed this article then help others by sharing it.
Happy learning, Vivek Rudrappa