I have a lightning component where I need to display link to related list of children relationship record for given custom object record.
Since I developed this application on sandbox, I can't hardcode this link since it will change after I deploy this application to production. So I was thinking of building the link dynamically by dynamically retrieving the custom field id.
This is short version of Lightning component
<aura:component controller="LEXCont">
<aura:attribute name="relatedLinkPrefix" type="String" />
<aura:attribute name="projectId" type="String" />
<a href="{!v.relatedLinkPrefix + v.projectId}" target="_blank" >Related months</a>
</aura:component>
These are two methods from LEXCont class
static String restGet(String endPoint, String method, String sid) {
Http h = new Http();
HttpRequest hr = new HttpRequest();
hr.setHeader('Authorization', 'Bearer ' + sid);
hr.setTimeout(60000);
hr.setEndpoint(endPoint);
hr.setMethod(method);
HttpResponse r = h.send(hr);
return r.getBody();
}
@AuraEnabled
public static String getRelatedDebugLink() {
try{
String baseURL = URL.getSalesforceBaseUrl().toExternalForm();
String monthObjectId = restGet( baseURL + '/services/data/v38.0/tooling/query?q=select+Id+from+CustomObject+where+DeveloperName+=+\'Month\'', 'GET', UserInfo.getSessionId() );
monthObjectId = monthObjectId.substringAfter('"Id":"').substringBefore('"');
String projectLookupFieldId = restGet( baseURL + '/services/data/v38.0/tooling/query?q=select+Id+from+CustomField+where+TableEnumOrId=\'' + monthObjectId + '\'AND+DeveloperName=\'Project\'', 'GET', UserInfo.getSessionId() );
projectLookupFieldId = projectLookupFieldId.substringAfter('"Id":"').substringBefore('"');
return '/' + Month__c.sobjecttype.getDescribe().getKeyPrefix() + '?rlid=' + projectLookupFieldId + '&id=';
} catch( Exception ex ){
throw new AuraHandledException( ex.getMessage() );
}
}
In this code I am trying to execute two Tooling API queries: the first one
Select Id from CustomObject where DeveloperName = 'Month'
to get custom Object Id and the next one
select Id from CustomField where TableEnumOrId=:monthObjectId AND DeveloperName='Project'
to get the actual custom field Id.
Since we can't run query on CustomField and CustomObject objects directly, I had to use REST API to make these queries.
I mean I can't just write inline queries like
SObject cs = [ select id from CustomObject ];
or
SObject cf = [ select id from CustomField ];
because if I try to do that I will receive error message
sObject type 'CustomObject' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names.
and
sObject type 'CustomField' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names.
correspondingly, because CustomObject and CustomField object are only exposed for Tooling API.
The code for getRelatedDebugLink method works fine if I use it from Anonymous Execution window or from Visualforce page but doesn't work for Lightning, since Lightning Session ID doesn't have to full access to Salesforce API.
When I run the same code from Anonymous execution window, I got the result custom field id but when I run this in Lightning, I receive error
This session is not valid for use with the REST API
I know that I could use some additional visualforce page proposed in this answer
<apex:page>
Start_Of_Session_Id{!$Api.Session_ID}End_Of_Session_Id
</apex:page>
which would give me full-access session id or I could hardcode my username and password and perform SOAP login to get full-access session id, however it would be too complex. I wonder if there is any concise or elegant solution to this