I am calling the Tooling API from Apex in order to find out if a Custom Field has been created. Here is my code:
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(Utils.GetBaseUrlForInstance()+'/services/data/v30.0/tooling/query/?q=Select+Id+from+CustomField+where+DeveloperName=\''+objAndField[1]+'\'+and+TableEnumOrId=\''+objAndField[0]+'\'');
req.setMethod('GET');
Http h = new Http();
HttpResponse res = h.send(req);
System.debug(res.getBody());
Dom.Document doc = res.getBodyDocument();
Dom.XMLNode xmlNode = doc.getRootElement();
Integer totalSize = Integer.valueOf(xmlNode.getChildElement('totalSize', null).getText());
return totalSize > 0;
And here is the log. You can see that the request succeeds and finds the CustomField but it chokes on converting it to a Dom.Document
19:05:55.047 (47524557)|CALLOUT_REQUEST|[793]|System.HttpRequest[Endpoint=https://na24.salesforce.com/services/data/v30.0/tooling/query/?q=Select+Id+from+CustomField+where+DeveloperName='sososo'+and+TableEnumOrId='Account', Method=GET]
19:05:55.192 (192996453)|CALLOUT_RESPONSE|[793]|System.HttpResponse[Status=OK, StatusCode=200]
19:05:55.193 (193056935)|SYSTEM_METHOD_EXIT|[793]|System.Http.send(ANY)
19:05:55.193 (193102469)|SYSTEM_METHOD_ENTRY|[794]|System.HttpResponse.getBody()
19:05:55.193 (193204909)|SYSTEM_METHOD_EXIT|[794]|System.HttpResponse.getBody()
19:05:55.193 (193248897)|SYSTEM_METHOD_ENTRY|[794]|System.debug(ANY)
19:05:55.193 (193265508)|USER_DEBUG|[794]|DEBUG|{"size":1,"totalSize":1,"done":true,"queryLocator":null,"entityTypeName":"CustomFieldDefinition","records":[{"attributes":{"type":"CustomField","url":"/services/data/v30.0/tooling/sobjects/CustomField/00N1a000002n3ETEAY"},"Id":"00N1a000002n3ETEAY"}]}
19:05:55.193 (193278096)|SYSTEM_METHOD_EXIT|[794]|System.debug(ANY)
19:05:55.193 (193295673)|SYSTEM_METHOD_ENTRY|[795]|System.HttpResponse.getBodyDocument()
19:05:55.193 (193517647)|EXCEPTION_THROWN|[795]|System.XmlException: only whitespace content allowed before start tag and not { (position: START_DOCUMENT seen {… @1:1)
19:05:55.193 (193612605)|SYSTEM_METHOD_EXIT|[795]|System.HttpResponse.getBodyDocument()
19:05:55.193 (193638491)|SYSTEM_MODE_EXIT|false
19:05:55.193 (193735001)|FATAL_ERROR|System.XmlException: only whitespace content allowed before start tag and not { (position: START_DOCUMENT seen {… @1:1)
I basically want to check that totalSize in the response is equal to 1. If it makes any difference, I'm calling the Tooling API from a @RemoteAction.
Best Answer
The REST API version of the Tooling API is returning JSON by default where you are trying to read it into an XML document.
You could either tell the REST API that you want XML in the response (Accept request header) or process the response as JSON.
It's a bit raw, but here is a JSON version.