What is Tooling Api?
Tooling api is for Building custom development tools for Force.com applications.
Tooling API makes many development tasks easier.
When to use Tooling API?
When You want to add functionality to your existing development and integration tools or you want to build specialized development tools for a specific application or service.
• Manage working copies of Apex classes and triggers and Visualforce pages and components using the ApexClassMember, ApexTriggerMember, ApexPageMember, ApexComponentMember and MetadataContainer objects.
• Manage working copies of static resource files using the StaticResource object.
• Check for updates and errors in working copies of Apex classes and triggers and Visualforce pages and components, and commit changes to your organization using the ContainerAsyncRequest object.
• Set heap dump markers using the ApexExecutionOverlayAction object.
• Overlay Apex code or SOQL statements on an Apex execution using the ApexExecutionOverlayAction object.
• Execute anonymous Apex. For sample code, see Using Tooling SOAP API and Using Tooling REST API.
• Set checkpoints to generate log files for yourself or for other users using the TraceFlag object.
• Access debug log and heap dump files using the ApexLog and ApexExecutionOverlayResult objects.
• Manage custom fields on custom objects using the CustomField object.
• Access code coverage results using the ApexCodeCoverage,
ApexOrgWideCoverage and ApexCodeCoverageAggregate objects.
• Execute tests, and manage test results using the ApexTestQueueItem and ApexTestResult objects.
• Manage validation rules and workflow rules using the ValidationRule and WorkflowRule objects
Tooling API provides both SOAP and REST interfaces.
Use REST API if you’re using a language that isn’t strongly typed, like JavaScript. The Tooling REST API can be used just like the Force.com REST API.
Resources
The base URI for each Tooling REST API resource is http://domain/services/data/vXX.X/tooling/ where domain is a Salesforce instance or a custom domain and vXX.X is the API version number.
Example:-http://na1.salesforce.com/services/data/v28.0/tooling/
Like the Force.com REST API, Tooling API uses the following resources.
URI
|
Supported Methods
|
Description
|
/completions?type=
|
GET
|
Retrieves available code completions of the referenced type.Currently only supports Apex system method symbols
(type=apex)
|
/executeAnonymous/?anonymousBody= <url encoded body>
|
GET
|
Executes Apex code anonymously.
|
/query/?q=
|
GET
|
Executes a query against a Tooling API object and returns data that
matches the specified criteria
|
/runTestsAsynchronous/?classids= <comma separated list of class
IDs> AND
/runTestsSynchronous/?classnames=<comma separated list of class
names>
|
GET
|
Executes the tests in the specified classes. Running tests
asynchronously allows methods to process in parallel, cutting down
your test run times.
|
/sobjects/
|
GET
|
Lists the available Tooling API objects and their metadata
|
/sobjects/SObjectName/
|
GET
|
Describes the individual metadata for the specified object or creates
a new record for a given object.use the GET method to retrieve the metadata for the ApexExecutionOverlayAction object.
|
/sobjects/SObjectName/
|
POST
|
Use the POST method to
create a new ApexExecutionOverlayAction object.
|
/sobjects/SObjectName/describe/
|
GET
|
Completely describes the individual metadata at all levels for the
specified object.
|
/sobjects/SObjectName/id/
|
GET
PATCH
DELETE
|
Accesses records based on the specified object ID.
Use the GET method to retrieve records or fields, the DELETE
method to delete records, and the PATCH method to update
records
|
/sobjects/ApexLog/id/Body/
|
GET
|
Retrieves a raw debug log by ID. Available from API version 28.0
or later.
|
EXAMPLES:
The following examples use Apex to execute REST requests
First, setup the connection to your org and the HTTP request type:
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
At the end of each request add the below code to send request and retrieve the body of the response.
Http h = new Http();
HttpResponse res = h.send(req);
system.debug(res.getBody());
To get a description of all available objects in Tooling API:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/sobjects/');
req.setMethod('GET');
req.setMethod('GET');
To get a description of a specific Tooling API object, for example TraceFlag:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/sobjects/
ApexClass/');
req.setMethod('GET');
To get a description of all the metadata for a specific Tooling API object, for example TraceFlag:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/sobjects/
ApexClass/describe/');
req.setMethod('GET');
To create a new Tooling API object, for example MetadataContainer:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/sobjects/
MetadataContainer/');
req.setBody('{"Name":"TestContainer"}');
req.setMethod('POST');
To retrieve a Tooling API object by ID, for example MetadataContainer:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/sobjects/ MetadataContainer/ + containerID + '/');
req.setMethod('GET');
To update a Tooling API object by ID, for example MetadataContainer:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/sobjects/ MetadataContainer/ + containerID + '/'); req.setBody('{"Name":"NewlyNamedContainer"}');
req.setMethod('PATCH');
To query a Tooling API object by ID, for example MetadataContainer:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/query/?q=
Select+id,Name+from+MetadataContainer+Where+ID=\'' + containerID + '\'');
req.setMethod('GET');
To check on the status of a deployment, using ContainerAsyncRequest:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/sobjects/
ContainerAsyncRequest/' + requestID + '/');
req.setMethod('GET');
Apex Class :-
To create an Apex Class using Tooling Api :
String json ='{ "Name" : "Mydemoclass1", "Body" : "public class Mydemoclass1{ public Void sayHello(){ string name= \'HI NAGARAJU\'; system.debug(\'***Name\'+name);} }" }';
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/sobjects/ApexClass');
req.setMethod('POST');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setBody(json);
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
To Update an Apex Class:
update an apex class involves some more steps than steps we required above. Apex class can be update by ApexClassMember Object.
Steps to update are:
- First we need to create Metadatacontainer object example:
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/MetadataContainer/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"Name":"TestMetadataContainer"}');
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
- After this we need to create ApexClassMember object if we want to update ApexClass.ApexClassMember require 3 parameters, MetadatacontainerId, ApexClass id (which is created previously) as ContentEntityId and full body of class as string which is updated.
- Here is example to create Apex Class so ApexClassMember will be created by:
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ApexClassMember/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"MetadataContainerId":"1dc90000000I6UwAAK","ContentEntityId" : "01p90000006Ll4tAAC","Body":"public class Mydemoclass1{ public Void sayHello(){ string name= \'HI NAGARAJU\';String Phone = \'9948839625\'; String Email = \'Nag@gmail.com\';system.debug(\'***Name\'+name);} } "}');
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
- To update a class ContainerAsyncRequest object is used. It compile and deploy the code and provide status of code. Is code deployed or has some problem and what is the problem. ContainerAsyncRequest object can be created by:
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"MetadataContainerId" : "1dc90000000I6UwAAK", "isCheckOnly": "false"}');
It returns the id by this, status of deployed code can be checked as:
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest/'+'1dr90000001rMK3AAM');
To Delete an Apex Class :
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() +'/services/data/v28.0/tooling/sobjects/ApexClass/'+01p90000006Ll4tAAC);
req.setMethod('DELETE');
Http h = new Http();
HttpResponse res = h.send(req);
system.debug(res.getBody());
Apex Trigger:
To create an Apex Trigger Using Tooling Api :
String json = '{ "Name" : "AccountTrigger", "TableEnumOrId" : "Account", "Body" : "trigger AccountTrigger1 on Account (before insert) { for(Account objacc : trigger.new){if(objacc.NManchala__Total_Amount__c > 1000){objacc.NManchala__Status__c = 'Clerk';} }}" }';
Httprequest req = new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v27.0/sobjects/ApexTrigger');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());
req.setBody(json);
Http httpReq = new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
To Update an Apex Trigger:
To update an apex trigger ,involves some more steps same as apex class.
- First we need to create Metadatacontainer object example:
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/MetadataContainer/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"Name":"TriggerMetadataContainer"}');
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
- Next we have to create an apextriggerMember object if we want to update ApexTrigger.apextriggerMember require 3 parameters, MetadatacontainerId, ApexTrigger id (which is created previously) as ContentEntityId and full body of trigger as string which is updated.
- Here is example to create Apex Class so apextriggerMember will be created by:
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ApexTriggerMember/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"MetadataContainerId":"1dc90000000I6VBAA0","ContentEntityId" : "01q90000000bbYRAAY","Body":"trigger AccountTrigger1 on Account (before insert) { for(Account objacc : trigger.new){if(objacc.NManchala__Total_Amount__c > 50000){objacc.NManchala__Status__c = \' Manager\';} }}"}');
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
- To update a Trigger ContainerAsyncRequest object is used. It compile and deploy the code and provide status of code. Is code deployed or has some problem and what is the problem. ContainerAsyncRequest object can be created by:
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"MetadataContainerId" : "1dc90000000I6VBAA0", "isCheckOnly": "false"}');
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
- It returns the id by this, status of deployed code can be checked as:
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest/'+1dr90000001rMQpAAM);
To delete an Apex Trigger:
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() +'/services/data/v28.0/tooling/sobjects/ApexTrigger/'+01q90000000bbYRAAY);
req.setMethod('DELETE');
Http h = new Http();
HttpResponse res = h.send(req);
system.debug(res.getBody());
Apex Page:
To create a Apex Page using Tooling Api
String json ='{ "Name" : "TestPageFromRest","Markup" : "<apex:page>hello</apex:page>","ControllerType" : "0","MasterLabel":"TestPageFromRest","ApiVersion":"29.0"}';
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/sobjects/ApexPage');
req.setMethod('POST');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setBody(json);
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
//for controllerType = >0 -- no controller,
//for controllerType => 1 -- Standard controller + extensions
//for controllerType => 3 --custom Controller
To update an Apex Page:
To update an apex Page,involves some more steps same as apexclass and trigger.
- First we need to create Metadatacontainer object example:
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/MetadataContainer/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"Name":"pageMetadataContainer"}');
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
- Next Create ApexPageMember .
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ApexPageMember/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"MetadataContainerId":"1dc90000000I6VGAA0","ContentEntityId" : "06690000005axNXAAY","Body":"<apex:page> <apex:form> <Apex:pageblock ></apex:pageblock></apex:form></apex:page>"}');
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
- Next create ContainerAsyncRequest object.
Httprequest req =new HttpRequest();
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest/');
req.setHeader('Content-Type','application/json');
req.setHeader('Authorization','OAuth ' + UserInfo.getSessionId());
req.setMethod('POST');
req.setBody('{"MetadataContainerId" : "1dc90000000I6VGAA0", "isCheckOnly": "false"}');
Http httpReq =new Http();
HttpResponse res = httpReq.send(req);
System.debug(res.getBody());
- It returns the id by this, status of deployed code can be checked as:
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+'/services/data/v28.0/tooling/sobjects/ContainerAsyncRequest/'+'1dr90000001rMR9AAM');
To Create Static Resource using Tooling API:
string name = 'testjs';
string contentType = 'text/javascript';
string body = 'alert("Hello World");';
// The static resource is expected to be base64 encoded.
string base64EncodedBody = EncodingUtil.base64Encode(Blob.valueof(body));
System.debug(base64EncodedBody);
HttpRequest req = new HttpRequest();
req.setEndpoint( URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v29.0/tooling/sobjects/StaticResource');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
// JSON formatted body
req.setBody(
'{"Name":"'+name+'"'+
',"ContentType":"'+contentType+'"'+
',"Body":"'+base64EncodedBody+'"'+
',"CacheControl":"Public"}'
);
Http http = new Http();
HttpResponse res = http.send(req);
System.debug(res);
System.debug(res.getBody());
System.debug(res.getHeaderKeys());
The Tooling Api consists of four types of objects.
1.Programming Objects.
2.Setup Objects.
3.Tooling Objects.
4.Operational Objects.
Programming Objects:
These Objects are used for interacting with programmatic artifacts for apex,visualforce and lightening.
The objects are:
Apexclass
ApexComponent
ApexPage
ApexTrigger
AuraDefinition
All the above objects Represents Saved Copy of their Respective.and
ApexClassMember
ApexComponentMember
ApexPageMember
ApexTriggerMember
AuraDefinitionBundle
Static Resource
Represents working copy of their respective for Editing, saving and compiling.
Tooling Objects:
These objects are for building tools around test results, debugging, code coverage, and more.
ApexCodeCoverage:- Represents code coverage test results for an Apex class or trigger.
select ApexClassorTrigger.Name,NumLinesCovered,NumLinesUncovered from ApexCodeCoverage ORDER BY ApexClassorTrigger.Name ASC.
ApexCodeCoverageAggregate:-Represents aggregate code coverage test results for an Apex class or trigger.
select ApexClassorTrigger.Name,NumLinesCovered,NumLinesUncovered from ApexCodeCoverageAggregate
ApexExecuteOverlayAction:- Specifies an Apex code snippet or SOQL query to execute at a specific line of code in an Apex class or trigger and optionally generate a heap dump.
ApexExecuteOverlayResult:-Represents the result from the Apex code snippet or SOQL query defined in the associated ApexExecutionOverlayAction, and the resulting heap dump if one was returned.
ApexLog :- Represents a debug log.
ApexOrgWideCoverage :- Represents code coverage test results for an entire organization.
SELECT PercentCovered FROM ApexOrgWideCoverage
ApexResult :- A complex type that represents the result of Apex code executed as part of anApexExecutionOverlayAction, returned in an ApexExecutionOverlayResult.
ApexTestQueueItem :- Represents a single Apex class in the Apex job queue.
HeapDump :- A complex type that represents a heap dump in an Apex Execution Overlay Result.
SOQLResult :- A complex type that represents the result of a SOQL query in an Apex ExecutionOverlayResult.
SymbolTable:A complex type that represents all user-defined tokens in the Body of an ApexClass,ApexClassMember, or ApexTriggerMember and their associated line and column locations within the Body.
select Id, ApiVersion, Name, NamespacePrefix, SymbolTable, Body from ApexClass where NamespacePrefix = 'Nmanchala'
TraceFlag :- Represents a trace flag that triggers an Apex debug log at the specified logging level.
Operational Objects:-
These objects are for Tooling API operations.
ContainerAsyncRequest :- Allows you to compile and asynchronously deploy a MetadataContainer object to your organization.
DeployDetails:-A complex type that contains detailed XML for any compile errors reported in the asynchronous request defined by a ContainerAsyncRequest object.
MetadataContainer :- Manages working copies of ApexClassMember, ApexTriggerMember, ApexPageMember and ApexComponentMember objects, including collections of objects that should be deployed together.
Setup Objects:- These objects are primarily used for interacting with metadata for declarative development.
All these Objects are Queryable objects by enabling the (Use Tooling API )Checkbox in developer console.
Object
|
Description
|
BusinessProcess
|
Represents a business process.
|
CompactLayout
|
Represents the values that define a compact page layout.
|
CustomField
|
Represents a custom field on a custom object that stores data unique to your organization.
|
CustomFieldMember
|
Represents the working copy of a field for editing or saving in a Metadata Container.
|
CustomObject
|
Represents a custom object that stores data unique to your organization. Includes access to the associated CustomObject object and related fields in Salesforce Metadata API.
|
CustomTab
|
Represents a custom tab.
|
EmailTemplate
|
Represents an email template.
|
EntityDefinition
|
Provides row based access to metadata about standard and custom objects.
|
FieldDefinition
|
Provides row based access to metadata about standard and custom fields of standard and custom objects.
|
FieldSet
|
Represents the metadata for a group of fields.
|
FlexiPage
|
Represents a Lightning Page. A Lightning Page is the home page for an app that appears as a menu item in the Salesforce1 navigation menu. Includes access to the associated FlexiPage object in the Salesforce Metadata API.
|
Layout
|
Represents a page layout. For more information, see “Managing Page Layouts” in the Salesforce online help.
|
MenuItem
|
Represents a menu item.
|
Profile
|
Represents a user profile. A profile defines a user's permission to perform different functions within Salesforce.
|
ProfileLayout
|
Represents a profile layout.
|
QuickActionDefinition
|
Represents the definition of a quick action.
|
QuickActionList
|
Represents a list of quick actions.
|
QuickActionListItem
|
Represents an item in a quick action list.
|
RecentlyViewed
|
Represents metadata entities typically found in Setup such as page layout definitions, workflow rule definitions, and email templates that the current user has recently viewed.
|
RecordType
|
Represents a custom record type.
|
User
|
Represents a user.
|
ValidationRule
|
Represents a formula that is used for specifying when a criteria is met. This includes both validation rules and workflow rules. Includes access to the associated ValidationRule object in the Salesforce Metadata API.
|
WorkflowAlert
|
Represents a workflow alert. A workflow alert is an email generated by a workflow rule or approval process and sent to designated recipients.
|
WorkflowFieldUpdate
|
Represents a workflow field update.
|
WorkflowOutboundMessage
|
Represents an outbound message. An outbound message is a workflow, approval, or milestone action that sends the information you specify to an endpoint you designate, such as an external service. Outbound messaging is configured in the Salesforce setup menu. Then you must configure the external endpoint. You can create a listener for the messages using the SOAP API.
|
WorkflowRule
|
Represents a workflow rule that is used to fire off a specific workflow action when the specified criteria is met. Includes access to the associated WorkflowRule object in Salesforce Metadata API.
|
WorkflowTask
|
Represents a workflow task that is used to fire off a specific workflow action when the specified criteria is met. Includes access to the associated WorkflowRule object in Salesforce Metadata API.
|
Thanks...best information about tooling api
ReplyDeleteWhat are the permissions needed for using it from a static method on a static apex class?
ReplyDeleteHow to right test classes for tooling api ,in case of updating workflow .
ReplyDeletenice one sir
ReplyDeleteUseful Document.Can we deactivate multiple trigger at one rest call?
ReplyDelete