How to Call Salesforce API from Lightning Component

You may have heard about that we can not make the Salesforce API Call directly from the lightning component. If you do make the callout from the lightning component then you will get the below error

INVALID_SESSION_ID:This session is not valid for use with the API.

For Example when you will execute the below code from the Developer Console then you will get the Valid Response


HTTP h = new HTTP();
HTTPRequest req = new HTTPRequest();
HttpResponse resp = new HttpResponse();

req.setMethod('GET');
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v41.0/query?q=Select+Id,+Name+From+Account');
resp = h.send(req);
System.debug('#### Response Status '+resp.getStatus());
System.debug('#### Response Status Code '+resp.getStatusCOde());
System.debug(resp.getBody());

But if you will call the same block from the Lightning Component then you will get INVALID_SESSION_ID:This session is not valid for use with the API. Error.

I gone through with this error and found THIS SALESFORCE DOCUMENT where they have specified why we can not make API Call from JavaScript Code.

After reading the document, I have come up with 2 Solutions that are given below: –

1 – Connected App and Named Credentials as Callout Endpoints and Auth Providers

2 – Using VF Page – VF page will be used to get the Session Id of the current log in user and this VF page will be used into Apex class for fetching the Session Id.

In this tutorial we will use VF page for making callout because it is an easy and simple method method. Follow the below steps

Step1 – Open Developer Console, File -> New -> VisualForce Page -> Enter Name “GetSessionIdVF” -> OK. Use below code for VF Page


<apex:page >
 Start_Of_Session_Id{!$Api.Session_ID}End_Of_Session_Id
</apex:page>

Step2 – Create a New Class which will use this VF page to get the Session Id and making API Call Out. File -> New -> Apex Class -> Name it “ApiCallLightningComponent” -> OK. Use below code for the class.


public class ApiCallLightningComponent {
 /*
 * @Name : - fetchUserSessionId
 * @Description: - Call the VF page and get the Log In Use Session Id
 * @Params : - none
 * @ReturnType : - String
 */
 public static String fetchUserSessionId(){
 String sessionId = '';
 // Refer to the Page
 PageReference reportPage = Page.GetSessionIdVF;
 // Get the content of the VF page
 String vfContent = reportPage.getContent().toString();
 System.debug('vfContent '+vfContent);
 // Find the position of Start_Of_Session_Id and End_Of_Session_Id
 Integer startP = vfContent.indexOf('Start_Of_Session_Id') + 'Start_Of_Session_Id'.length(),
 endP = vfContent.indexOf('End_Of_Session_Id');
 // Get the Session Id
 sessionId = vfContent.substring(startP, endP);
 System.debug('sessionId '+sessionId);
 // Return Session Id
 return sessionId;
 }
 /*
 * @Name - makeAPICall
 * @Description - Responsible for making API Call out
 * @params - None
 * @ReturnType - String
 */
 @AuraEnabled
 public static String makeAPICall(){
 String sessionId = fetchUserSessionId();
 HTTP h = new HTTP();
 HTTPRequest req = new HTTPRequest();
 HttpResponse resp = new HttpResponse();
 req.setMethod('GET');
 req.setHeader('Authorization', 'Bearer ' + sessionId);
 req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v41.0/query?q=Select+Id,+Name+From+Account');
 resp = h.send(req);
 System.debug('#### Response Status '+resp.getStatus());
 System.debug('#### Response Status Code '+resp.getStatusCOde());
 System.debug(resp.getBody());
 return JSON.serialize(resp.getBody());
 }
}

See the comments.

ApiCallLightningComponent class contains 2 methods fetchUserSessionId and makeAPICall, One for getting the Session Id and Other for making the Callout that will be called from the JavaScript.

Step3 – Create a lightning component, File -> New -> Lightning Component -> Name it “MakiAPICall” -> OK. Use below code for the Component


<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes, flexipage:availableForRecordHome,force:hasRecordId, forceCommunity:availableForAllPageTypes, force:lightningQuickAction" controller="ApiCallLightningComponent" access="global" >
<div class="slds-m-around_x-small">
			<lightning:button variant="brand" label="Make CallOut" iconName="action:apex" iconPosition="left" onclick="{!c.doHandleClick }" /></div>
</aura:component>

Click on the Controller and use below code


({
doHandleClick : function(component, event, helper) {
helper.onHandleClick(component, event, helper);
}
})

Click on the helper and then use below code for helper


({
onHandleClick : function(component, event, helper) {
// Get the action of Controller (Apex) Class
var action = component.get('c.makeAPICall');

// set the callback which will return the response from apex
action.setCallback(this, function(response){
// get the state
var state = response.getState();
if( (state === 'SUCCESS' || state ==='DRAFT') && component.isValid()){
// get the response
var responseValue = response.getReturnValue();
// Parse the respose
var responseData = JSON.parse(responseValue);
alert(responseData);
//alert(responseData.totalSize);
console.log(responseData);
} else if( state === 'INCOMPLETE'){
console.log("User is offline, device doesn't support drafts.");
} else if( state === 'ERROR'){
console.log('Problem saving record, error: ' +
JSON.stringify(response.getError()));
} else{
console.log('Unknown problem, state: ' + state +
', error: ' + JSON.stringify(response.getError()));
}
});
// send the action to the server which will call the apex and will return the response
$A.enqueueAction(action);
}
})

Step4 – In Final Step Test the Component using Lightning Application. File -> New -> Lightning Application -> Enter Name -> Submit -> Use below Code


<aura:application extends='force:slds' >
<c:MakiAPICall/>
</aura:application>

Note: – If Your component name is different then use the name of your component instead of MakiAPICall.

Output of the above code

Call API From Lightning Component

You can find the complete Here.

Happy Learning 🙂

Happy Coding 😉

Sharing is Caring

Resources –

 

Advertisements

8 thoughts on “How to Call Salesforce API from Lightning Component

  1. Jesse Chase September 21, 2018 / 8:25 pm

    Any idea why i’d get ‘Ending position out of bounds: -1’ in my debug log when following your instructions?

    Like

  2. Nitish Bansal April 3, 2018 / 9:52 am

    This has performance issues with data rows > 20

    Like

    • Amit Singh April 3, 2018 / 9:59 am

      Nitish,

      fetch all the records from Apex to javascript controller and then parse the same in javascript to increase the performance.

      Like

  3. xialijsun February 22, 2018 / 12:22 am

    I have tried out this solution, however on my lightning component when I invoke the auraEnabled function when it is try to read content from the page I got error:
    FATAL_ERROR System.VisualforceException: org.apache.commons.httpclient.RedirectException: Maximum redirects (100) exceeded

    Like

    • Amit Singh February 22, 2018 / 3:14 am

      This is what I need to check. I will get back to you ASAP.

      Like

    • Amit Singh February 22, 2018 / 7:01 am

      Hi Are you using the Exact Code that I have posted over Here because I have tested the same in my other developer ORG and it is working fine.

      Regards,
      Amit

      Like

    • Amit Singh February 5, 2018 / 6:03 am

      Glad you liked it.

      Please do share with your friends because sharing is caring 🙂 😉

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s