Integrating With Salesforce Using Apex

Introduction

This article concludes the series, Learning Salesforce Integration, which details various integration options with Salesforce. It covers using Apex for building integrations, which becomes a necessity for not-so-straight-forward scenarios. Though the scenarios listed here are simple, the idea is to share code snippets that can be used to quickly build a working interface.

So why take the programmatic path? Well, when I started learning Salesforce, I was curious about how Salesforce handled interfacing, more so, when it came to dealing with complex business scenarios. Coding comes to the rescue in such situations. It proves advantageous in terms of flexibility and offers control over certain situations.

For this post, I’ll offer a simple explanation  of the complex, yet interesting areas essential for the complete understanding of Salesforce Integration’s capabilities. The business scenario quoted, along with the working code samples, will be a good starting point for entering into the world of non-declarative ways for integrating with Salesforce. Here’s what I’ll cover:

  • Understanding authentication and its prerequisites
  • OAuth authentication flows for REST API calls
  • Apex triggers and callouts
  • REST API, REST web services, and Apex web services

Authentication and Its Prerequisites

Authenticating a client application is the first and foremost step while building an interface. Once authenticated, we developers are only limited by our skills (and of course by the business requirement) because programming languages provide abundant capabilities for building and implementing logic that cater to any complex requirement. Further, the direction of the call’s flow decides the interfacing ends, i.e., the source and the destination.

The authentication method depends on your chosen call type (REST or SOAP). Like in my first post, I integrated Siebel with Salesforce using SOAP. So I used the SOAP API login() call. Let’s see how to do it using REST.

Before moving any further, let’s frame a business scenario. We’ll use two Salesforce instances that exchange Account details. When a new Account is created in one org, it will flow down to the other Salesforce org, and in return the source org will get the Salesforce Record ID of the created record. These two orgs are:

  • Source Salesforce org (used for callout) – Instance S
  • Target Salesforce org (used for receiving requests) – Instance T

I planned it this way because you don’t need to depend on any other client application, and you get to learn about interfacing for both outbound and inbound calls together.

Following our business scenario, we can say that authentication is a collection of the following sub-steps. Though actual authentication calls a trigger from the Apex code, consider these steps as the prerequisites because without them being completed first, the authentication calls won’t work.

  1. Remote Site Setting in Instance S
  2. Connected App in Instance T
  3. Choosing OAuth Endpoint (to be invoked from Instance S)
  4. Choosing OAuth Authentication flow (to be used by Instance S)

Remote Site is any web address that your organization can invoke from Salesforce. For any callout to work (whether SOAP or REST), the called domain (or the domain of Instance T) needs to be registered as a remote site in Instance S. The idea behind it is to prevent any calls to unauthorized network addresses.

Figure 1: Setup | Security Controls | Remote Site Settings | Remote Site Details

 Connected App enables Salesforce to recognize and authenticate an external application as a new entry point. OAuth is used for this authentication. We need to create a Connected App record in Instance T so it can inform Salesforce about the new authentication entry point (Instance S). Below is an illustration.

Figure 2: Connected App

Important information to be mentioned in the Connected App record:

  • API Name: Any name that is a meaningful representation of Instance S
  • Enable OAuth Settings: Checkbox to be checked
  • Selected OAuth Scopes: Scope of access allowed to Instance S
  • Callback URL: URL the user needs to be redirected to after authentication

On saving this record, the system generates the Consumer Key (clientId) and the Consumer Secret (clientSecret) that are used while making the authentication call to the OAuth Endpoint. This is detailed later while discussing the code samples.

Next, we’ll follow the choice of an OAuth endpoint to be used while issuing authentication requests from Instance S. The primary OAuth endpoints are:

  • For authorization: https://login.salesforce.com/services/oauth2/authorize
  • For token requests: https://login.salesforce.com/services/oauth2/token
  • For revoking OAuth tokens: https://login.salesforce.com/services/oauth2/revoke

In our scenario, we use the second endpoint to receive the access token. This access token can then be used in subsequent business logic or data requests from Instance S to Instance T.

OAuth Authentication Flows

The REST API calls can be authenticated using any of the available three flows:

Web Server OAuth Authentication Flow – The client application requests the authorization server to redirect the user to another web server or resource that authorizes the user and sends the application an authorization code. The application uses the authorization code to request an access token.

User-Agent OAuth Authentication Flow – The client application requests the authorization server to redirect the user to another Web server or resource that is capable of extracting the access token, and passing it back to the application.

Username-Password OAuth Authentication Flow – This flow can be used to authenticate when the consumer already has the user’s credentials for the target instance.

I have used the Username-Password flow in the business scenario. Using this flow usually means that we plan to use a separate Salesforce User (we can call it an Integration User) to access the target Salesforce instance. This user’s access can be limited to whatever we wish, using its Profile settings, and can be used by various systems that integrate to the Salesforce instance.

To sum up, we have configured a few of the settings and made our choices about the authentication endpoint and flow. Now we’ll continue learning about coding an Apex Trigger, ApexClass, Authentication call, Data Request call, and Response manipulation.

Handling the Need Using Apex Trigger

Unlike other programming languages, Apex has a limited scope as defined by Salesforce. It surfaces only when we are not able to achieve the result using Point-And-Click or the Declarative approach.

Apex Trigger, as a Database trigger, refers to a piece of Apex code that sits and waits for a particular event (Data Manipulation Language event, DML) to occur. When that happens, it executes the code written to achieve the desired result. It is usually constructed using Apex-defined keywords and SOQL.

I find defining a trigger as one easy way to perform a callout, though the call that is made is asynchronous. So the user needs to refresh the page in case any update from the response has been made to the currently displayed record. An example of making a synchronous callout can be the use of a Visualforce page, but that is not in scope of this article.

trigger SendAccount on Account* (after** insert***)
{
1 for(Account a : Trigger.new)
  {
2   SendAccountUsingRESTAPI.callcreateAcc(a.Name, a.Id);
  }
}

Code Sample 1: APEX Trigger

Explanation –

  • * The object on which this Trigger is based
  • ** The execution moment, i.e., before or after
  • *** The operation, like insert, update, etc.
  • 1 Optimized to operate in bulk for handling more than one record at a time
  • 2 Invoking an @future method of a class with required arguments

After a new Account record is inserted into the database, this trigger is invoked. It can handle more than one Account record, which is helpful when dealing with bulk data load. Finally, the trigger calls a public class that has a method annotated with @future. The @future annotation provides a way to perform a callout asynchronously.

Generating the Access Token

Once the above trigger executes, it makes a call to the class that is mentioned. This class does the actual authentication processing and data exchange. In brief, the defined custom class performs three main tasks:

  1. It retrieves an access token from Instance T to authenticate Instance S. It is an HTTP POST request that uses the OAuth Endpoint, along with the Consumer Key and Consumer Secret generated from the Connect App record. The response is then deserialized to retrieve the access token.
  2. It makes a data call to Instance T. This call can be a REST API/SOAP API call (Data Layer) or REST/Apex Web Service call (Business Logic Layer) and depends on our need or the complexity of the requirement. We will discuss REST API, REST Web Service, and Apex Web Service separately to understand the general code to be used.
  3. It handles the response from Instance T, deserializes it, and updates Instance S with the relevant information.

In this section, we’ll discuss  the first task.

public class SendAccountUsingRESTAPI {
1  private final String clientId = '4GE…….ATL';
   private final String clientSecret = '892….465';
   private final String username = 'abc@abc.com';
   private final String password = 'testpwd5t…T9';
2  public class deserializeResponse
   {
      public String id;
      public String access_token;
   }
3  public String ReturnAccessToken (SendAccountUsingRESTAPI acount)
   {
      String reqbody = 'grant_type=password&client_id='+clientId+'&client_secret='+clientSecret+'&username='+username+'&password='+password;
4     Http h = new Http();
      HttpRequest req = new HttpRequest();
      req.setBody(reqbody);
      req.setMethod('POST');
      req.setEndpoint('https://login.salesforce.com/services/oauth2/token');
      HttpResponse res = h.send(req);
5     deserializeResponse resp1 = (deserializeResponse)JSON.deserialize(res.getbody(),deserializeResponse.class);
      return resp1.access_token;
   }
6  @future(callout=true)
   public static void callcreateAcc (String accName, String accId)
   {
      SendAccountUsingRESTAPI acount1 = new SendAccountUsingRESTAPI();
      String accessToken;
7     accessToken = acount1.ReturnAccessToken (acount1);
      …………
   }
}

Code Sample 2: Defining class and retrieving access token

Explanation –

  • 1 Declared as class variables, this is secret information generated from the Connected App record and a pair of integration user credentials that can be used for interfacing
  • 2 An inner class to be used for deserializing the JSON response
  • 3 Class method that takes in the class variables and returns the access token after authentication
  • 4 Preparing the HTTP Request for authentication
  • 5 Deserializing the response to obtain the access token using JSON.deserialize()
  • 6 Future annotation where the call from the trigger lands in this class; it tells the system that this method will be making a callout asynchronously
  • 7 Call to the ReturnAccessToken method passing an instance of the class; response is the actual access token that can be used further

Exchanging Data and Decoding the Response

After extracting the access token from the authentication call, we need to make the subsequent call for data exchange. The code structure is similar with few differences. Ours being a simple scenario, the code should be easy to understand.

The data exchange flow goes like this. After the new Account is inserted into the database of Instance S, it is sent to Instance T in a POST call. This creates an Account record in Instance T and returns back the Account ID. The code then extracts the Account ID from the response and updates the Account record in Instance S.

Moving to the second and third tasks performed by the class, we recognize the need for using either of the available ways to integrate, i.e., REST/SOAP API or REST/Apex Web Service. So which one should we use when? Well… If you’re building the interface in the morning before your bath, use SOAP, and if it’s late evening,  use REST 😀

Seriously, I answer these simple questions to decide the appropriate method:

  • What does the interfacing system support – SOAP or REST?
    This doesn’t leave you with much of a choice, but you can still decide on whether to use the predefined API calls or customized calls, depending on the answers to the next set of questions.
  • Is there a lot of data to exchange?
    For lesser amounts of data you can go with any REST API or SOAP API (though REST offers better performance). In case you have large amounts of data, it’s better to use SOAP.
  • How simple or complex are the data exchanges?
    For a simple, straightforward data exchange with respect to a single object, use REST API, and in the case of data having relationships like Parent-Child, to be created in a single call, use SOAP API.
  • Is the business process around the data exchange complex?
    To deal with the complexity of the business process, which you are not able to cater to by using the predefined APIs,  go for the custom integration built using Apex, but this should ideally be the last option chosen.

Though for our scenario we should use REST API, we will discuss all the methods, except SOAP API (which we covered in Force.com SOAP API Sample WSDL Structures), so as to understand them.

REST API

Let’s check out the code sample below for the Apex Callout that uses REST API resources for making a call to Instance T.

@future(callout=true)
public static void callcreateAcc (String accName, String accId) {
   SendAccountUsingRESTAPI acount1 = new SendAccountUsingRESTAPI();
   String accessToken = acount1.ReturnAccessToken (acount1);

   if(accessToken != null){
1     String endPoint = 'https://na16.salesforce.com/services/data/v32.0/sobjects/Account/';
2     String jsonstr = '{"Name" : "' + accName + '"}';

      Http h2 = new Http();
      HttpRequest req1 = new HttpRequest();
3     req1.setHeader('Authorization','Bearer ' + accessToken);
      req1.setHeader('Content-Type','application/json');
      req1.setHeader('accept','application/json');
      req1.setBody(jsonstr);
      req1.setMethod('POST');
      req1.setEndpoint(endPoint);
      HttpResponse res1 = h2.send(req1);

      deserializeResponse resp2 = (deserializeResponse)JSON.deserialize(res1.getbody(),deserializeResponse.class);
4     Account a = [SELECT Id FROM Account WHERE Id = :accId];
5     a.Siebel_Id__c = resp2.id;
      update a;
   }
}

Code Sample 3: Exchanging data (REST API), extracting response

Explanation –

  • 1 Setting the REST API resource to create an Account (sObject)
  • 2 Creating the JSON string to be sent as the input
  • 3 Setting the Header to include the access token
  • 4 Querying the Account record in Instance S so it can be updated
  • 5 Setting the custom foreign key field on Account in Instance S with the extracted Account ID from the response

REST Web Service

Next, if we used REST Web Service instead of REST API, there would be few differences. First, we need to have a global class exposed as a web service at the target instance (this was not required in the case of REST API). Second, change the called endpoint at the source to point to the correct web service resource at the target. Third, handle the special characters introduced in the response at the source.

if(accessToken != null){
1  String endPoint = 'https://na16.salesforce.com/services/apexrest/v1/createAccount/';
   String jsonstr = '{"AccName" : "' + accName + '"}';

   Http h2 = new Http();
   HttpRequest req1 = new HttpRequest();
   req1.setHeader('Authorization','Bearer ' + accessToken);
   req1.setHeader('Content-Type','application/json');
   req1.setHeader('accept','application/json');
   req1.setBody(jsonstr);
   req1.setMethod('POST');
   req1.setEndpoint(endPoint);
   HttpResponse res1 = h2.send(req1);

2  String trimmedResponse = res1.getBody().unescapeCsv().remove('\\');
   deserializeResponse resp2 = (deserializeResponse)JSON.deserialize(trimmedResponse, deserializeResponse.class);
   Account a = [SELECT Id FROM Account WHERE Id = :accId];

   a.Siebel_Id__c = resp2.id;
   update a;
}

Code Sample 4: Exchanging data (REST Web Service), extracting response – written at the source instance

Explanation –

  • 1 Setting the endpoint to the web service exposed in Instance T
  • 2 The target sends a serialized response, which is received with some extra characters at the source, so removing the extra characters here
1  @RestResource(urlMapping='/v1/createAccount/*')
   global with sharing class createAccount {
2     @HttpPost
      global static String createAccount(String AccName){
3        Account a = new Account();
         a.Name = AccName;
         insert a;
4        String returnResponse = JSON.serialize(a);
5        return returnResponse;
      }
   }

Code Sample 5: REST Web Service exposed at the target

Explanation –

  • 1 Exposing the web service using the @RestResource annotation
  • 2 Exposing method as REST resource to be called when HTTP Post request is made to this web service
  • 3 Creating a new Account in Instance T and setting the name as passed from Instance S
  • 4 Serializing the response (Account details) before sending
  • 5 Sending the response

Apex Web Service

Finally, the third option is the Apex Web Service that uses SOAP to handle integration. The class written at the target needs to be exposed as a global Web Service.

1  global class CreateAccountApexWS {
      global class sAccount{
2        webservice String name;
      }
3     webservice static String createAccount(sAccount sAcct){
         Account acct = new Account();
         acct.Name = sAcct.name;
         insert acct;
         String returnResponse = JSON.serialize(acct);
         return returnResponse;
      }
   }

Code Sample 6: APEX Web Service exposed at the target

Explanation –

  • 1 Creating a Global class that can be accessed from anywhere
  • 2 Using the webservice keyword to expose class variable as an input to the web service
  • 3 Using the webservice keyword to expose the class method as a custom SOAP Web Service

To test this code you can generate a WSDL from the Salesforce instance (Setup | Build | Develop | Apex Classes) and import it into SoapUI. Then pass the sessionId in the request message, along with the Account Name to be created.

Apex Code Test Coverage

I started as a tester and soon swam into the developer pool. But during that short time I developed a keenness towards maintaining quality standards. I consider testing a two-step process. First, ensure that the product being developed is defect-free. Second, it should have high quality standards, i.e., best practices should be appropriately followed.

Testing in Salesforce is also an integral part of the development process. It gives quality assurance before deploying anything into Production. Frankly, I found the Salesforce testing procedure, especially for the code, as interesting as developing a requirement.

These quality checks are enforced by creating and executing Unit Tests. Unit Tests consist of test methods and classes that verify whether a particular piece of code is working properly. They are also written in Apex. It is important to understand:

  • Unit Tests are required to deploy Apex to a production environment.
  • They are also required if your code is going to be packaged and placed on AppExchange.
  • The test methods must provide at least 75% code coverage.
  • Code coverage is calculated by dividing the number of unique Apex code lines executed during your test method execution by the total number of Apex code lines in all of your triggers and classes.

A question – why didn’t I highlight testing earlier in the post? Because we have been using the development org. So if we had to move any of the code into production or package it for AppExchange, we would have written Unit Tests with 75% code coverage.

Summary

Now, concentrating on what we discussed, let me reiterate what we’ve just learned:

  • Identifying Interface Direction – Identify the integration flow with respect to your Salesforce organization, i.e., outbound or inbound
  • Outbound – Build a Callout with the following:
    • Remote Site for the target app
    • Apex Trigger that initiates the Callout on the required DML event
    • Apex Class with an @future method that calls the target app endpoint
  • Inbound – If the flow is inbound, then for working with REST principles, you can use either REST API or REST Web Service, and for SOAP, you can use either SOAP API or Apex Web Service. The decision should be based on the complexity involved and if the incoming message needs manipulation. Create the following in your Salesforce instance:
    • Connected App record, this generates the Consumer Key and Consumer Secret that can be used by the client app to authenticate with your Salesforce organization.
    • Create an Apex Class exposed as a REST Web Service using @RestResource annotation, or as an Apex Web Service using the webservice keyword for the global class method.

In short, follow the series Learning Salesforce Integration.

We learned ‘how to integrate with Salesforce.’

References

About the Author

Anupam Rastogi is a CRM Consultant working in CSC, who has a rich experience in popular CRM products like Salesforce and Oracle Siebel CRM. He has published the series of posts, Learning Salesforce Integration, that discusses interfacing with/from Salesforce.

Previous posts in the series:

He can be reached @ anupam.rastogi@gmail.com or LinkedIn Profile.

 

Leave your comments...

Integrating With Salesforce Using Apex