Force.com Tooling API issues

I just tried to implement Tooling API using REST API and did some basic callouts:

  • create a Apex class
  • creating a apex trigger
  • editing apex class
  • query a tooling api object
  • delete a apex class

out of these 5 tries, i got succeed in three. By tooling api I was able to create a Apex class and delete a apex class and query a objects.

Rest of my tries:-

When I try to edit a apex class which i created before

it always comes with a error UNABLE TO ACCESS OBJECT FROM A CROSS REFERENCE ID . I tried it in several ways changing letter cases, changing HTTP METHOD but no method works. Setting correct configuration according to Salesforce Winter ’14 tooling API guide but it shows same error UNABLE TO ACCESS OBJECT FROM A CROSS REFERENCE ID. Why this error comes? Is some special access is required with these callout?

My code is

HttpRequest req = new HttpRequest();
req.setEndpoint('https://ap1.salesforce.com/services/data/v28.0/tooling/sobjects/ApexClass/'+oid+'?_HttpMethod=PATCH');
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setBody('{"Name":"NewApexClass1","Body":"public class TheApexClass1 { // DO SOMETHING }"}');
req.setMethod('POST');

I am not sure what going wrong here.

After I tried to create ApexTrigger but I stuck with TableEnumOrId. If I give it a name e.g Lead it says invalid object or... and if I don’t mention, it show MISSING FIELD. I have read about creating ApexTrigger by Tooling API everywhere on internet but there is no answer for it. Work arounds are only that use simple REST API to create a trigger. If anybody has some good reason, why this is error? please share some knowledge. If there are more issues regarding tooling API then please share.

Note: Already read all question regarding tooling api on this site , developerforce community and several other places.

Answer

As Adam points out, and the Tooling API docs, you need to use a MetadataContainer. From the Tooling API Developer’s Guide (pg.12)

To edit, save, or compile Apex classes, use ApexClassMember

Here is the reason: Apex must be compiled to ensure that all syntax and references are valid. For example, if I patch an ApexClass’s name field, another class that uses that field (MyClass.MyStaticMethod()) is on longer valid. Salesforce could compile for you behind the scenes, but this poses several problems.

  1. Salesforce would then be doing more (much more) than the intended field patch, reducing the visibility into what is actually going on.
  2. A compile may take a long time. It wouldn’t be good for the patch to take 5 minutes to return.

That is where the ContainerAsyncRequest comes in. It is explicitly saying, “I want to compile and save these changes to my org, and it may take a little while.”

I agree the guide could provide more information on this point, and the describe metadata is misleading.

Creation is a little different though. A class will (most often) not contain complex references when it is created and (more importantly) no other classes will be referencing it. Also, an ApexClassMember must have an existing ApexClass to reference, so we must create it though the actual ApexClass

In terms of creating a trigger, it is the same as creating a class except that you need the TableEnumOrId. The table enum is the name of the sObject you want to trigger on. For example:

A post to the following resource with the following data will create an Apex Trigger.

https://<instance>/services/data/v29.0/tooling/sobjects/ApexTrigger

Body: "trigger aa on Account (before insert) {}"
TableEnumOrId: "Account"

I’m not sure why you were getting the invalid object or... error. I was able to create a trigger on Lead by replacing Account in the TableEnumOrId field AND in the body.

EDIT:

I just tried again in Summer’13 and got the same error message. The reason why you are getting that error is because Lead (or Account) is not accessible in the Tooling API. In other words, when a trigger is created via the Tooling API it tries to reference the object that it is triggering on. When this happens, it throws that error because the object is no accessible in the Tooling API. This has been fixed in Winter’14.

Attribution
Source : Link , Question Author : Ashwani , Answer Author : Thomas

Leave a Comment