9

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?

1 Answer 1

8

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, 2020 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, 2020 at 19:56
  • Darn, that is disappointing to hear. Ah well. Thank you for clarifying! :)
    – kyoshioka
    Apr 10, 2020 at 15:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .