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.
Solution:
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
- Use provider as Salesforce
- Add Consumer Key and Consumer Secret from above mentioned connected app
- Authorize Endpoint and Token Endpoint will added automatically
- Use ‘full’ as Default Scope
- 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.
-
- Select Identity Type – Named Principle
- Select Authentication Provider – OAuth 2.0
- Select Authentication Provider from lookup. Use above created Auth Provider
- scope as full
- When we save named credential it will authenticate user.
- 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 Listrecords {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
6 comments
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
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
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
Hello Tarun,
Please check the client id created using the connected app. Looks like the client id is not correct.
Thank You,
Dhanik
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.
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