Skip to main content

How to Invoke Salesforce Tooling APIs and External REST APIs in LWC

In modern Salesforce development, Lightning Web Components (LWC) provide a fast and modular architecture for constructing rich user interfaces. Beyond rendering standard platform records, developers frequently need to query platform metadata via the Salesforce Tooling API or connect to external web services directly from client-side LWC controllers or supporting Apex adapters.

In plain words: Invoking Tooling or external REST APIs from an LWC allows your UI to retrieve platform metadata (such as Apex class details or custom field definitions) or fetch data from third-party services in real time.

1. Setting Up the Development Environment

Before making API requests inside Lightning Web Components, ensure your local tooling and Salesforce environment are configured properly:

  • Salesforce CLI: Installed to manage org connections, execute deployments, and test API calls.
  • Node.js & npm: Essential for maintaining LWC dependencies, running linting tools, and executing local unit tests.
  • VS Code with Salesforce Extensions: The standard IDE for editing LWC code and deploying metadata to scratch orgs or sandboxes.
  • CORS & Remote Site Settings: Any external API or internal Tooling endpoint called directly from client JavaScript or Apex must be registered under Remote Site Settings or CORS in Salesforce Setup.

2. Invoking the Salesforce Tooling API via Apex

Because browser security controls restrict direct web calls to internal tooling endpoints with session tokens, the recommended approach is using a lightweight Apex controller adapter to query the Tooling API endpoints securely.

First, create an Apex controller to execute the HTTP request to the Tooling REST endpoint:

// ToolingService.cls
public with sharing class ToolingService {
    @AuraEnabled(cacheable=true)
    public static String getApexClassDetails(String className) {
        String baseUrl = System.Url.getOrgDomainUrl().toExternalForm();
        String endpoint = baseUrl + '/services/data/v60.0/tooling/query/?q=SELECT+Id,Name,ApiVersion,Status+FROM+ApexClass+WHERE+Name=\'' + String.escapeSingleQuotes(className) + '\'';
        
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setMethod('GET');
        req.setHeader('Authorization', 'Bearer ' + Page.SessionIdFetcher.getContent().toString().trim()); // or Named Credential
        req.setHeader('Content-Type', 'application/json');

        Http http = new Http();
        HttpResponse res = http.send(req);
        return res.getBody();
    }
}

Next, call this Apex controller method directly inside your Lightning Web Component JavaScript controller:

// toolingViewer.js
import { LightningElement, wire, track } from 'lwc';
import getApexClassDetails from '@salesforce/apex/ToolingService.getApexClassDetails';

export default class ToolingViewer extends LightningElement {
    @track classData;
    @track error;

    connectedCallback() {
        getApexClassDetails({ className: 'MyTargetClass' })
            .then((result) => {
                this.classData = JSON.parse(result);
            })
            .catch((err) => {
                this.error = err.body ? err.body.message : err;
            });
    }
}
Developer Trap: Browser security (LWR / Lightning Locker) blocks client-side Node.js execution methods like child_process inside LWC JavaScript runtime files. Node modules and CLI commands run in your local developer machine environment, whereas browser LWCs must use fetch requests or Apex controllers to communicate with platform APIs!

3. Invoking External REST APIs from LWC

For standard third-party REST endpoints that support Cross-Origin Resource Sharing (CORS), you can execute HTTP requests directly from LWC using the standard Web API fetch() method:

Real-Life Example: Fetching live external JSON data directly within the browser without writing custom Apex endpoint handlers.
// externalDataFetcher.js
import { LightningElement, track } from 'lwc';

export default class ExternalDataFetcher extends LightningElement {
    @track responseData;
    @track errorMessage;

    connectedCallback() {
        const apiUrl = 'https://api.example.com/v1/data';

        fetch(apiUrl, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json'
            }
        })
        .then((response) => {
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }
            return response.json();
        })
        .then((data) => {
            this.responseData = data;
        })
        .catch((error) => {
            this.errorMessage = error.message;
        });
    }
}
Key Summary: API Integration Rules in LWC
  • Tooling API Strategy: Route requests through Apex controllers or Named Credentials to satisfy session security requirements.
  • Client-side Fetch: Use standard JavaScript fetch() for direct REST integrations when CORS is configured in Salesforce Setup.
  • CORS Configuration: Whitelist target API origin domains under Setup -> Security -> CORS for client-side JavaScript access.
  • Error Handling: Always process HTTP errors using promise catch blocks to provide graceful fallback messages to end users.

Conclusion

Invoking Salesforce Tooling APIs and external REST endpoints greatly expands the capabilities of Lightning Web Components. Whether you route requests through secure Apex HTTP wrappers or call public APIs directly using standard JavaScript fetch(), incorporating API integrations helps build dynamic, data-rich user interfaces on the platform.