Sunday, January 6, 2019

Salesforce rest api integration to fetch a record from external system

 Following are the most commonly used salesforce api:

1) Rest api
2) Soap api
3) Bulk api
4) Streaming api

First let's see when to use rest api as we have lot of other salesforce api.

Rest api is a simple and power webservice based on restful principles and it uses rest resource and HTTP methods to expose functionalities. It supports both XML and JSON . Rest api has lightweight requests and responsive framework and it is good for mobile and web apps.

Out of above mentioned salesforce api, in this blog post we will trying to cover the topic salesforce rest api integration by taking example of two salesforce systems.

Let say I have two salesforce org, ORG A and ORG B.

We will try to fetch account record from ORG B using apex rest callout from ORG A and display the account record using visualforce page in ORG A.

Let's start,

ACTIVITIES WE NEED TO DO IN ORG B.

1) Create a connected app.
2) Rest api webservice to fetch account record  and send it back to ORG A.

1) WHAT IS CONNECTED APP IN SALESFORCE?

For an external application that needs to authenticate with salesforce application, we need to create a connected app so as to inform about the new authentication entry point. Connected app uses standard OAuth 2.0 protocol to authenticate.

Salesforce api


Note down the Consumer key, Consumer secret(We need to provide it ORG A for authentication purpose along with username, password, security token of the user which ORG A will be using for authentication).

2) REST API WEBSERVICE:

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

   global with sharing class getContactRecord {

        @Httpget

      global static Contact fetchContact(){

        Contact obj=new Contact();

        RestRequest req = RestContext.request;

        RestResponse res = Restcontext.response;

        Map<String, String> requestParam = req.params;

        String conEmail=requestParam.get('email');

        String conPhone=requestParam.get('phone');

        obj=[Select id,lastname,email,phone from contact where email=:conEmail and phone=:conPhone];

       /***Modify the HTTP status code that will be returned to external system***/

        res.statuscode=201;

       /***Modify the HTTP status code that will be returned to external system***/

        return obj;

      }

   }


ACTIVITIES WE NEED TO DO IN ORG A.

1) Create an apex controller.
2) Create a visualforce page.
3) Create a remote site setting for the URL of System B.

Create a custom metadata to store the username, password, Consumer key, Consumer secret provided by ORG B as shown below.

Note: The password will be combination of password and security token.

Salesforce to Salesforce rest api integration example

Now, create a record under the above custom metadata as shown below.

Salesforce to Salesforce rest api integration example

1) CREATE AN APEX CONTROLLER:

public class restApiTofetchSingleRecord {

    private string cKey;

    private string cSecret;

    private string uName;

    private string passwd;

    public string instanceURL;

    public static list < resultWrapper > listWrap {

        get;

        set;

    }

    public restApiTofetchSingleRecord() {

        listWrap = new list < resultWrapper > ();

    }

    public class responseWrapper {

        public string id;

        public string access_token;

        public string instance_url;

    }

    public responseWrapper getRequestToken() {

        List < Store_Cred__mdt > connectionParam = [SELECT Id, MasterLabel, client_id__c, client_secret__c, username__c, password__c from Store_Cred__mdt];

        if(connectionParam.size() >0){

        cKey=connectionParam[0].client_id__c;

        cSecret=connectionParam[0].client_secret__c;

        uName=connectionParam[0].username__c;

        passwd=connectionParam[0].password__c ;

        }

        System.debug('Store_Cred__mdt' + connectionParam);

        string reqBody = 'grant_type=password&client_id=' + cKey + '&client_secret=' + cSecret + '&username=' + uName + '&password=' + passwd;

        Http h = new Http();

        HttpRequest req = new HttpRequest();

        req.setBody(reqBody);

        req.setMethod('POST');

        req.setEndpoint('https://login.salesforce.com/services/oauth2/token');

        HttpResponse hresp = h.send(req);

        responseWrapper wResp = (responseWrapper) JSON.deserialize(hresp.getBody(), responseWrapper.class);

        system.debug('reqBody '+reqBody );

        system.debug('wResp'+wResp );

        system.debug('Instance url' + wResp.instance_url);

        system.debug('session id' + wResp.access_token);

        return wResp;

    }

    public void getConList() {

        string integration1 = 'Testing integration';

        list < account > accList1 = new list < account > ();

        String accToken;

        String instanceUrl;

        string responseBody;

        string email = 'testemail123@gmail.com';

        string phone = '123';

        restApiTofetchSingleRecord obj = new restApiTofetchSingleRecord();

        responseWrapper obj1= obj.getRequestToken();

        accToken = obj1.access_token;

        instanceUrl = obj1.instance_url;

        string endPoint = instanceURL+'/services/apexrest/getContactFromEmailAndPhone/?' + 'email=' + email + '&phone=' + phone;

        system.debug('endPoint'+endPoint );

        system.debug('access token' + accToken);

        if (accToken != '') {

            Http h1 = new Http();

            HttpRequest req1 = new HttpRequest();

            req1.setHeader('Authorization', 'Bearer ' + accToken);

            req1.setHeader('Content-Type', 'application/json');

            //req1.setHeader('Accept','application/json');

            req1.setMethod('GET');

            req1.setEndpoint(endPoint);

            HttpResponse hresp1 = h1.send(req1);

            system.debug('hresp1'+hresp1 );

            system.debug('hresp1.getStatusCode()'+hresp1.getStatusCode());

             system.debug('hresp1.getBody()'+hresp1.getBody());

            if (hresp1.getStatusCode() == 201) {

                resultWrapper wResp1 = (resultWrapper) JSON.deserialize(hresp1.getBody(), resultWrapper.class);

                listWrap.add(wResp1);

            }

        }

    }

    public class resultWrapper {

        public string id {

            get;

            set;

        }

        public string LastName{

            get;

            set;

        }

        public string Email{

            get;

            set;

        }

        public string Phone{

            get;

            set;

        }

    }

}


2) CREATE A VISUALFORCE PAGE:

<apex:page controller="restApiTofetchSingleRecord">

<apex:form >

<apex:pageBlock >

 <apex:pageblockButtons >

 <apex:commandButton value="TEST" action="{!getConList}"/>

 </apex:pageblockButtons>

  <apex:pageblocktable value="{!listWrap}" var="a" >

 <apex:column value="{!a.LastName}"/>

 <apex:column value="{!a.Email}"/>

 <apex:column value="{!a.Phone}"/>

 </apex:pageBlockTable>

 </apex:pageBlock>

 </apex:form>

</apex:page>


3) Remote site URL:


The remote site url here is nothing but the instance URL of ORG B.


Now, Let's preview the visualforce page.

Salesforce to Salesforce rest api integration example

12 comments:

  1. How to we do the same if we need to display any Images?

    ReplyDelete
    Replies
    1. Sorry for the late reply. I have not checked yet, but I will update here if i try the same.

      Delete
  2. If its using Named Credentials, what changes we need to make on Apex controller?

    ReplyDelete
  3. Hi, after login is success how can we open SYSTEM B's home page? Thanks

    ReplyDelete
  4. How can we hide username, password, client secret etc from the apex class?

    ReplyDelete
    Replies
    1. You can use custom labels or custom settings or custom metadata to store username, password, client secret etc and than refer them in apex class.

      Delete
    2. Just use Named Credentials

      Delete
  5. Hello, the response of the oauth call is "access_token":"SESSION_ID_REMOVED"?
    How fix this?

    ReplyDelete
    Replies
    1. In debug log you will not be able to see it. however in class you can access it.

      Delete
  6. Hi, How to I include composite data in request body?

    ReplyDelete
  7. Hello, Iam not able to see connected app under create apps? can anyone help me please

    ReplyDelete