REST API Lightning Component

In this Salesforce Stack Exchange question I asked how to call the Salesforce REST API, specifically the analytics API, from a Lightning Component.  Two really good answers were given.  One was a great and thorough explanation, from Doug Chasman, of the security mechanisms in the framework.  The other was a great answer, from Marty Chang, that provided a workaround to call the REST API by going through Apex.

With his answer, Marty supplied this gist.  I expanded on Marty’s gist to create a generic component for calling the REST API from a Lightning component.  The rest of this article details portions of that component along with different ways of invoking it.  All code is available in this gist.

The Component

The component supports being called with a path, a method, a response format, and an optional body and body content type. It makes the request on its init event and it uses a component level event to communicate its response.

The controller’s makeRequest method calls the Apex controller’s service method and then fires an event with the response from the Apex controller as the event parameter.

The Apex controller builds an HttpRequest, sends it, and returns a custom Response object instance.  Note that the properties of that object are all specified as @AuraEnabled.

Note that the returned Response object’s body is a String, which could vary in format (e.g., JSON or XML) depending on the request.  The code could be enhanced to abstract the conversion from a JSON string to an object or from an XML string to an XML document, if desired.

A limitation of this implementation is that only supports those methods listed as supported by the HttpRequest.setMethod().  For example, PATCH is not supported.  The code could be enhanced to support that with the _HttpMethod query string override method.

Using The Component

The application or component that instantiates the component needs to specify an event handler to handle the result of the call.  For example, the following calls the Analytics API’s describe resource to get information about a report.

Here’s a contrived example that inserts an Account.

It is unlikely that the usage of a POST to insert an object would be useful, since that can be done easily enough with DML.  The above is just a simple illustrative example.  However, there are methods in other APIs where a POST could be more practical (e.g., Analytics API execute body).

Dynamic Invocation

Another possible use case would be executing the request based on user input.  For example, the user could be presented with a list of reports from which to choose and upon choosing one, the component could be called with the newly selected value.  In the following code, the select element specifies a controller method to handle the onchange.

The setPath method gets the value of the currently selected option, gets a reference to the restRequest component and calls its makeRequest method.  One thing to note, that is very powerful, is that even though the select is a plain old HTML element (i.e., not a component in the ui namespace), it is still treated as a first-class component by the framework.

Dynamic Component Creation

Lightning components don’t need to be explicitly created in markup.  They can also be created dynamically in JavaScript using the $A.componentService.newComponentAsync method.  Something like the following could be done to create an instance and call its action on the fly.

It specifies that an instance of the component be created with the specified attribute values.  In the callback function the event handler is set and the request action is enqueued to be called.

Thoughts and More

This article explained how the REST API could be called with a generic component, but it should be used with caution.  Each call counts towards the API limit and depending upon your app’s requirements a better non REST API solution might be available.  To learn more about the Lightning Component Framework visit the Salesforce1 Lightning Developer page.  To learn more about the REST API take a look at the REST API Developer’s Guide.  To learn more about the Analytics REST API check out the Salesforce1 Reporting REST API Developer Guide.

All code for this article is available in this gist.


10 thoughts on “REST API Lightning Component

  1. I’ve spent a lot of time writing Aura/Lightning, Polymer, and other JavaScript apps, and I just cant understand how making components which do this kind of thing, fetching data, is a good idea. In your article, the valuable thing to learn is seeing how to write the client-to-server connection code. But showing how to wrap that in a custom component? I think teaching this technique is a mistake, as it confuses noobies with good and bad practices. Putting app logic into your app via a view component shouldn’t be a normal thing.

    What’s your opinion on this? Am I missing something here? Is using XML as our app’s logic language really a good idea?

    Lightning is a feat of engineering, for sure, so I also find it interesting to play with. Thanks for the post!

    1. Great points. Most of this was just me experimenting with it. I definitely wouldn’t ever use this for anything like DML or DB manipulation. I’d possibly use it for something like getting data from a REST endpoint like the analytics API, but I’d weigh it against just using the connection code, possibly from a static resource if possible, in my own non-generic component.

  2. Hi Peter,

    Nice article but I hate to be the bearer of bad news – Summer ’15 closes the hole where UserInfo.getSessionId() in Apex gives you back an API capable session ID and the approach described will no longer function. When Apex is invoked by a Lightning controller action the same limited Lightning specific session ID should have been returned even server side. We will be publishing the Salesforce Security team “blessed” proxy approach that does not leak the more powerful session ID.


  3. Hi Peter,

    Nice article.

    I have an another quick question for you to check whether you have faced this before or not.
    As Lightning components events are relayed by Salesforce and the situation that I am having is that we are currently listening to a single search result event where the same search result event is being handled by many components.

    Now when I am trying to call a REST service call on the same event handler, I am getting the below FATAL Error :
    “FATAL_ERROR|System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out”
    I am NOT making any database transaction as part of this event handling; but yes other components are doing that.
    Is there any way to handled the event relay programmatically?

    Have you ever find yourself in this kind of situations?

    Any quick help would be appreciated.

  4. However, there are differences and concepts specific to Lightning Component inheritance to keep in mind which will be covered in detail in the rest of this post.

  5. However, there are differences and concepts specific to Lightning Component inheritance to keep in mind which will be covered in detail in the rest of this post.

  6. The contactSearch component creates the event, sets its parameters, and fires it after the search has completed. This code resides in a helper function that is called from a controller function.

  7. Hi Peter,

    I’ve been working on a KanBan project for a while. Basically, there are some components, events and client-side controllers in my app. And KanBan Console lists items of sObject that is indicated by Configuration object. I use fieldsets to decide which fields will be shown on each sObject item on KanBan Console.

    Unless, given sObject has fieldset on it, I try to make a HTTP callout for retrieving fields from compact layout of sObject via Salesforce Rest API. But when i attempt to use “UserInfo.getSessionId()” method, i receive “Response:[body=[{“message”:”This session is not valid for use with the REST API”,”errorCode”:”INVALID_SESSION_ID”}], status=Unauthorized, statusCode=401]” as response. Request headers etc. are OK. Finally, i decided to use your class and structure that are given above, but nothing has changed.

    What can i do? What is your advice? Thanks..

Leave a Reply

Your email address will not be published. Required fields are marked *