How to use Tooling API in Apex?

How to use Tooling API in Apex?

On May 29, 2025, Posted by , In Apex,Salesforce Technical Questions, With Comments Off on How to use Tooling API in Apex?
How to use Tooling API in Apex

Question:

How can I use the Tooling API in Salesforce to create an Apex class programmatically within an Apex controller? I am particularly interested in seeing an example that demonstrates how to achieve this. I have already generated MetadataService from WSDL but am open to other approaches, including REST-based methods.

Answer:

You can use the Tooling API in Salesforce through its REST-based interface to create an Apex class. Below is an example demonstrating how to achieve this by sending an HTTP POST request to the Tooling API endpoint. Ensure the base URL of the Tooling API is added as a Remote Site in your Salesforce org.

Get expert Salesforce certification guidance, interview prep, and hands-on Salesforce training in Pune—sign up for a free demo today!

// Class variable for Tooling API base URL
// This constructs the Tooling API endpoint dynamically.
private static String baseUrl = URL.getSalesforceBaseUrl().toExternalForm() 
    + '/services/data/v28.0/tooling/';

public static void createClass() {
    // Define the body of the Apex class to be created
    String classBody = 'public class MyNewClass {\\n'
        + ' public string sayHello() {\\n'
        + '  return \'Hello\';\\n' 
        + ' }\\n'
        + '}';

    // Construct the HTTP request
    HTTPRequest req = new HTTPRequest();
    req.setEndpoint(baseUrl + 'sobjects/ApexClass');
    req.setMethod('POST');
    req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
    req.setHeader('Content-Type', 'application/json');
    req.setBody('{' +
        '"Body" : "' + classBody + '"' +
    '}');

    // Send the HTTP request
    Http h = new Http();
    HttpResponse res = h.send(req);

    // Check the response status
    if (res.getStatusCode() != 201) {
        System.debug('Error creating class: ' + res.getBody());
        throw new MyException(res.getStatus());
    } else {
        System.debug('Class created successfully: ' + res.getBody());
    }
}

Explanation:

  1. Base URL: The base URL dynamically resolves to the Salesforce Tooling API endpoint using URL.getSalesforceBaseUrl().
  2. Authorization: The OAuth token (session ID) is added as a Bearer token in the Authorization header.
  3. Request Body: The Body field in the JSON request specifies the source code for the new Apex class.
  4. Remote Site Settings: Ensure the Tooling API base URL is added to Remote Site Settings for the API call to work.

Alternative Approaches:

If you’ve already generated MetadataService from WSDL, you can also use the Metadata API. However, this involves more complexity compared to the straightforward REST-based Tooling API method shown above. REST is preferred for quick operations like creating or modifying metadata, as it requires fewer steps and boilerplate code.

Example 1: Querying Existing Apex Classes with Tooling API

In addition to creating classes, you can query existing Apex classes using the Tooling API to retrieve metadata or source code.

public static void queryApexClasses() {
    String queryUrl = URL.getSalesforceBaseUrl().toExternalForm() 
        + '/services/data/v28.0/tooling/query?q=' +
        EncodingUtil.urlEncode('SELECT Id, Name, Body FROM ApexClass', 'UTF-8');

    HTTPRequest req = new HTTPRequest();
    req.setEndpoint(queryUrl);
    req.setMethod('GET');
    req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
    req.setHeader('Content-Type', 'application/json');

    Http h = new Http();
    HttpResponse res = h.send(req);

    if (res.getStatusCode() == 200) {
        System.debug('Query Results: ' + res.getBody());
    } else {
        System.debug('Error querying classes: ' + res.getBody());
        throw new MyException(res.getStatus());
    }
}

Example 2: Deleting an Apex Class

The Tooling API also allows deletion of metadata like Apex classes using an HTTP DELETE request.

public static void deleteClass(String classId) {
    String deleteUrl = URL.getSalesforceBaseUrl().toExternalForm() 
        + '/services/data/v28.0/tooling/sobjects/ApexClass/' + classId;

    HTTPRequest req = new HTTPRequest();
    req.setEndpoint(deleteUrl);
    req.setMethod('DELETE');
    req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());

    Http h = new Http();
    HttpResponse res = h.send(req);

    if (res.getStatusCode() == 204) {
        System.debug('Class deleted successfully.');
    } else {
        System.debug('Error deleting class: ' + res.getBody());
        throw new MyException(res.getStatus());
    }
}

Explanation of Alternatives

1.Metadata API Approach:

Using the MetadataService class generated from WSDL, you can deploy metadata like Apex classes. However, this involves more setup and is generally more suitable for bulk operations or when managing complex metadata changes. Here’s a simplified example of using the Metadata API:

MetadataService.MetadataService service = new MetadataService.MetadataService();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();

MetadataService.ApexClass apexClass = new MetadataService.ApexClass();
apexClass.apiVersion = 58.0;
apexClass.fullName = 'MyGeneratedClass';
apexClass.content = 'public class MyGeneratedClass { public String greet() { return "Hello!"; } }';

MetadataService.AsyncResult[] results = service.createMetadata(new MetadataService.Metadata[] { apexClass });
System.debug('Deployment Results: ' + results[0].id);

2.Tooling API vs Metadata API:

  • Tooling API: Best for real-time, lightweight operations like creating or updating single Apex classes, triggers, or other metadata.
  • Metadata API: Preferred for bulk operations, deployments, or when modifying metadata types not supported by Tooling API.

3.Combining SOQL Queries with Tooling API:

You can enhance the Tooling API functionality by combining it with SOQL. For instance, you could query Tooling API objects like ApexTrigger or CustomObject.

String query = 'SELECT Id, Name FROM ApexTrigger';
String queryUrl = URL.getSalesforceBaseUrl().toExternalForm() 
    + '/services/data/v28.0/tooling/query?q=' + EncodingUtil.urlEncode(query, 'UTF-8');

Master Salesforce with Expert Training in Pune

Embark on a transformative learning journey with our industry-leading Salesforce training in Pune. Designed to cater to aspiring professionals, our training offers specialized tracks in Administration, Development, and AI, ensuring comprehensive skill development. Gain expert-led certification guidance, participate in advanced interview preparation, and access in-depth class notes tailored for industry readiness.

Experience a practical, job-focused approach with live projects and interactive sessions that build your expertise in Salesforce technologies. Salesforce training Whether you’re starting your journey or aiming to upskill, our program equips you with the knowledge and confidence to excel in the competitive job market.

Join our free demo class today and take the first step toward achieving your career aspirations in Salesforce!!!

Comments are closed.