Home Salesforce Call Tooling API from Lightning Web Component

Call Tooling API from Lightning Web Component

by Dhanik Lal Sahni

Tooling API is used for custom development tools or apps for Lightning Platform applications. Tooling API’s SOQL capabilities for many metadata types allow us to retrieve smaller pieces of metadata.

I was having a requirement to get list of all page layout for my object using Tooling API.  I have called Tooling API from apex and used UserInfo.getSessionId() as authentication token.  But when i called that apex method from lightning web component, i was getting below error.

INVALID_SESSION_ID:This session is not valid for use with the Rest API.
 
So our UserInfo.getSessionId() will not work as authentication token when we call Tooling API from lightning web component.

Solution:

We have to use Connected App, Auth Provider and Named Credential combination for solving this issue. Let us create them to be used for calling Tooling API.

1. Connected App

First create connected app to get consumer key and secret. These key and secret will be used in Auth Provider to authenticate logged in user.

For this step just use http://login.salesforce.com/services/authcallback for callback url.  We will update this url once Auth Provide is ready.

2. Auth Providers

Create new Auth provider from setup.  Use below information for setting up Auth Provider

  1. Use provider as Salesforce 
  2. Add Consumer Key and Consumer Secret from above mentioned connected app
  3. Authorize Endpoint and Token Endpoint will added automatically
  4. Use ‘full’ as Default Scope
  5. Select user from Execute Registration As lookup.  That user will be used for authentication token generation internally

Once Auth Provider will be created it will generate Salesforce configuration URLs.

Copy Callback Url and update callback url in Connected App’s callback url. 

3. Named Credential

Create named credential using Auth Provider.

    1. Select Identity Type – Named Principle
    2. Select Authentication Provider – OAuth 2.0
    3. Select Authentication Provider from lookup. Use above created Auth Provider
    4. scope as full
    5. When we save named credential it will authenticate user.  
    6. Enter user credential and allow access for app.

Component Code:

Apex Code:

We are ready now for creating apex code which will be used above created named credential to call Tooling API.

 public static String restGet(String endPoint, String method, String sid) {
        try
        {
            Http h = new Http();
            HttpRequest hr = new HttpRequest();
            hr.setHeader('Authorization', 'Bearer ' + sid);
            hr.setTimeout(60000);
            hr.setEndpoint(endPoint);
            hr.setMethod(method);
            HttpResponse r = h.send(hr);
            return r.getBody();
        }
        catch(Exception ex)
        {
            system.debug('Exception in tooling API Call:'+ ex.getMessage());
            return ex.getMessage();
        }
}
 
public static String toolingAPISOQL(string query) {
        String baseURL='callout:ToolingRest?';  //Named Credential
        return restGet( baseURL +'q='+ (query.replace(' ', '+')),'GET', UserInfo.getSessionId());
} 
    
public static List<string> getLayoutNameForObject( string objectName ) {
        string sql='select Layout.Name from ProfileLayout where TableEnumOrId=\'objectName\'';
        String body = toolingAPISOQL(sql.replace('objectName', objectName));
        if(string.isNotBlank(body))
        {
            LayoutRecord data=LayoutRecord.parse(body);
            
            //get only layput name
            List<string> layouts=new List<string>();
            for(LayoutRecord.Record record:data.records)
            {
                if(!layouts.contains(record.Layout.Name))
                {
                    layouts.add(string.valueOf(record.Layout.Name));
                }
            }
            return layouts;
        }
        return null;
    }

LayoutRecord Wrapper Class

public class LayoutRecord {
    
    public Integer size {get;set;} 
	public Integer totalSize {get;set;} 
	public Boolean done {get;set;} 
	public Object queryLocator {get;set;} 
	public String entityTypeName {get;set;} 
	public List records {get;set;} 
    
    public class Layout {
		public Attributes attributes {get;set;} 
		public String Name {get;set;} 
    }
    public class Attributes {
		public String type_Z {get;set;} // in json: type
		public String url {get;set;} 
    }
    public class Record {
		public Attributes attributes {get;set;} 
		public Layout Layout {get;set;} 
    } 
        
    public static LayoutRecord parse(String json){
		return (LayoutRecord) System.JSON.deserialize(json, LayoutRecord.class);
	}
}

Lightning Web Component Code:

import getLayout from '@salesforce/apex/PageLayoutController.getObjectLayout';
@wire(getLayout, { objectName : 'Account' }) layouts;

Now we can get layout information by calling apex code from Lightning Web Component.

Related Posts

Salesforce DevOps for Developers: Enhancing Code Quality and Deployment Efficiency

Apex Code Coverage In Custom Object

Get All Used Custom Metadata Detail

Find Referenced Metadata using Salesforce Dependency API

Extract list of all fields from Page Layout

Field Access Explorer In lightning Web Component

Call Tooling API from Lightning Web Component

You may also like

6 comments

M Sahitya September 25, 2020 - 11:20 am

will this work for all profiles in my org, or for each user do i need to created connected app with “execute registration as”. Thanks in advance

Reply
Dhanik Lal Sahni September 29, 2020 - 8:40 am

Hello Sahitya, You need to create connected app once. You can assign profile and permission set to user. Based on user credential, access is provided in org. Give least access to user which is used by connected app.

Thank You,
Dhanik

Reply
Tarun Gyanchandani October 7, 2022 - 10:36 am

Tried in my developer edition org, it’s working. But while trying in Sandbox in the last step, while saving the named credentials, when it supposed to redirect to the login page, it’s throws an error as invalid client id

Reply
Dhanik Lal Sahni October 15, 2022 - 9:51 pm

Hello Tarun,

Please check the client id created using the connected app. Looks like the client id is not correct.

Thank You,
Dhanik

Reply
Eric March 1, 2024 - 10:03 pm

I could not get the named Credentials to save it keeps giving me an error when I save it. error=redirect_uri_mismatch&error_description=redirect_uri%20must%20match%20configuration
I have both the same and it still does not save.

Reply
Dhanik Lal Sahni March 8, 2024 - 8:40 pm

Hello Eric,
callback url in the connected app should be the same as you have in your redirect_uri. Please check and confirm on this solution.

Thank You,
Dhanik

Reply

Leave a Comment