5

I am using Salesforce's REST API to (1) retrieve a list of object IDs according to a query, then (2) retrieve the records that correlate to those IDs. I am familiar with the Salesforce composite documentation here.

My request looks like this:

POST: /services/data/v48.0/composite

{
    "allOrNone":false,
    "compositeRequest": [ {
        "method":"GET",
        "url": "/services/data/v48.0/query?q=SELECT+Id+FROM+My_Entity+WHERE+(CreatedById+!=+'asdfghjkl')",
        "referenceId": "myEntity"
        },{
        "method":"GET",
        "url": "/services/data/v48.0/composite/sobjects/My_Entity?ids=@{myEntity.records[0].Id}",
        "referenceId":"myObject"
    }]
}

My response:

{
    "compositeResponse" : [ {
        "body" : {
            "totalSize" : 21,
            "done" : true,
            "records" : [ {
                "attributes" : {
                    "type" : "My_Entity",
                    "url" : "/services/data/v48.0/sobjects/My_Entity/a0D6g000xxxxxxx"
                },
                "Id" : "a0D6g000xxxxxxx"
                }, {*record2*}, {*etc*}
            ]},
            "httpHeaders" : { },
            "httpStatusCode" : 200,
            "referenceId" : "myEntity"
        }, {
        "body" : [ {
        "errorCode" : "PROCESSING_HALTED",
        "message" : "'myEntity.records' references an invalid Datatype. Only Strings and primitive data types are allowed to be referenced from previous operations."
        } ],
        "httpHeaders" : { },
        "httpStatusCode" : 400,
        "referenceId" : "myObject"
    } ]
}

The first subrequest (the query) executes without errors. My problem is the second subrequest. I understand from Salesforce documentation that I can refer to the ID of a single item (e.g. myEntity.records[0].Id). Question: How do I use all items from myEntity.records in the second subrequest?

4

The indexing of (a list of) referenced records is relative to the body key, the expected syntax is @{<reference>.records[x].<field>}. Here's a working request:

POST to /services/data/v48.0/composite

{
    "allOrNone":false,
    "compositeRequest": [ {
        "method":"GET",
        "url": "/services/data/v48.0/query?q=SELECT+Id+FROM+Account",
        "referenceId": "accts"
        },{
        "method":"GET",
        "url": "/services/data/v48.0/query?q=SELECT+Name+FROM+Account+WHERE+Id='@{accts.records[0].Id}'",
        "referenceId":"myObject"
    }]
}

Response with redacted IDs:

{
   "compositeResponse": [
      {
         "body":
         {
            "totalSize": ...,
            "done": true,
            "records": [
               {
                  "attributes":
                  {
                     "type": "Account",
                     "url": "/services/data/v48.0/sobjects/Account/001..."
                  },
                  "Id": "001..."
               }
            ]
         },
         "httpHeaders": {},
         "httpStatusCode": 200,
         "referenceId": "accts"
      },
      {
         "body":
         {
            "totalSize": 1,
            "done": true,
            "records": [
               {
                  "attributes":
                  {
                     "type": "Account",
                     "url": "/services/data/v48.0/sobjects/Account/001..."
                  },
                  "Name": "Some Account Name"
               }
            ]
         },
         "httpHeaders": {},
         "httpStatusCode": 200,
         "referenceId": "myObject"
      }
   ]
}
3
  • Hello, thank you for your answer! I understand that @{<reference>.records[x].<field>} is the correct syntax. However, I would like to use all record items in my second subrequest, not just the first item in the list. Does this mean that I need to have multiple subrequests, each hardcoded with an index? (i.e. @{accts.records[0].Id}, @{accts.records[1].Id}, @{accts.records[2].Id}, etc)
    – kyoshioka
    Apr 9 '20 at 15:25
  • Oops, pardon for less than helpful answer. Unfortunately there's no way to do this out of the box, it won't do a join of values across records for you. You could create a custom Apex REST service or you can do a join on the client side and then issue another request..
    – identigral
    Apr 9 '20 at 19:56
  • Darn, that is disappointing to hear. Ah well. Thank you for clarifying! :)
    – kyoshioka
    Apr 10 '20 at 15:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.