Constructing composite requests
The /composite endpoint
To create a composite request, use the /composite endpoint in the
Composite API. This is different than batches. Every API has its own /batch
endpoint. But in all of Cloud API, there is only one /composite endpoint,
and it is in the Composite API.
The syntax for the composite request call is:
POST <applicationURL>/rest/composite/v1/composite
Sections of a composite request
A composite request can have up to two sections:
- A
requestssection, which contains the subrequests that commit data. - A
selectionssection, which contains the subselections that query for data. These are executed after the subrequests, and only if all the subrequests commit data successfully.
At a high level, the syntax for these sections is as follows:
{
"requests": [
{
<subrequest 1>
},
{
<subrequest 2>
},
...
],
"selections": [
{
<subselection 1>
},
{
<subselection 2>
},
...
]
}
The requests section
In the requests section, the only supported operations are POST,
PATCH, and DELETE. This includes both POSTs that create data and POSTs that execute business
actions (such as POST /assign).
The basic syntax for the requests section is shown below.
{
"requests": [
{
"method": "<post/patch/delete>",
"uri": "<path>",
"body": {
"data": {
"attributes": {
"<field1>": "<value1>",
"<field2>": "<value2>",
...
}
}
}
},
{
<next subrequest>
},
...
{
<final subrequest>
}
]
}
For example, the following simple composite request creates two notes for activity xc:202.
POST <applicationURL>/rest/composite/v1/composite
{
"requests": [
{
"method": "post",
"uri": "/common/v1/activities/xc:202/notes",
"body": {
"data": {
"attributes": {
"body": "Cloud API note #1."
}
}
}
},
{
"method": "post",
"uri": "/common/v1/activities/xc:202/notes",
"body": {
"data": {
"attributes": {
"body": "Cloud API note #2."
}
}
}
}
]
}
For the complete syntax that includes all composite request features, see Complete composite request syntax.
Using variables to share information across subrequests
Information from one subrequest can be used in later subrequests. You can do this through the use of composite variables.
Declaring variables
Composite variables are declared in a subrequest's vars section. Each
variable has a name and path. The name is
an arbitrary string. The path specifies what to set the variable to. It is
set to a JSON path expression that identifies a value in the subrequest's response payload.
For example, suppose a subrequest that creates an activity has the following:
"vars": [
{
"name": "newActivityId",
"path": "$.data.attributes.id"
}
]
This creates a variable named newActivityId, which is set to the value of
the data section's attributes section's id field (which
would typically be the id of the newly created activity).
Referencing variables
To reference a variable, use the following syntax:
${<varName>}
You can use variables anywhere in the body of a subrequest. The most common uses for variable values are:
- In an
attributesfield - Within the path of a
uri - As part of a query parameter
For example, suppose there is a subrequest that creates an activity, and it is followed by
a subrequest that creates a note. The first subrequest creates a
newActivityId variable as shown previously. The uri for
the second subrequest is:
"uri": "/common/v1/activities/${newActivityId}/notes"
This would create the new note as a child of the first subrequest's activity.
The following is the complete code for the previous examples.
{
"requests": [
{
"method": "post",
"uri": "/claim/v1/claims/cc:34/activities",
"body": {
"data": {
"attributes": {
"activityPattern": "contact_insured",
"subject": "Cloud API activity"
}
}
},
"vars": [
{
"name": "newActivityId",
"path": "$.data.attributes.id"
}
]
},
{
"method": "post",
"uri": "/common/v1/activities/${newActivityId}/notes",
"body": {
"data": {
"attributes": {
"body": "Cloud API note #1."
}
}
}
}
]
}
Responses to the subrequests
The response to a composite request contains a responses section. This section contains one subresponse for each subrequest. Every subresponse has three sections:
- A
bodysection, which by default contains the default response data defined in the corresponding endpoint. - A
headerssection, which contains any custom headers. - A
statusfield, which indicates the subresponse's status code.
For example, the following is the responses section and the first subresponse for a composite request whose first subrequest created an activity:
"responses": [
{
"body": {
"data": {
"attributes": {
"activityPattern": "contact_insured",
"activityType": {
"code": "general",
"name": "General"
},
"assignedByUser": {
"displayName": "Andy Applegate",
"id": "demo_sample:1",
"type": "User",
"uri": "/admin/v1/users/demo_sample:1"
},
...
},
"checksum": "0",
"links": {
"assign": {
"href": "/common/v1/activities/cc:403/assign",
"methods": [
"post"
]
},
...
}
}
},
"headers": {
"GW-Checksum": "0",
"Location": "/common/v1/activities/xc:403"
},
"status": 201
},
Fields whose values are generated when data is committed
The individual subresponses to each subrequest specify data that has technically not been committed yet. However, some fields contain values that are not generated until the data is committed.
When a subresponse includes a value that is generated as part of the commit, Cloud API makes effort to match the data that will be committed as closely as possible. For example, the composite request reserves ID values so that these IDs can be provided in subresponses and committed to the database.
But, there are some fields for which Cloud API cannot match the value. For example, when
executing a POST, the values for createTime and updateTime
cannot be determined prior to the commit. Fields of this type are always omitted from a
subrequest's subresponse. But, they can be retrieved through a subselection.
Subresponse values can be out of date
As noted above, the individual subresponses to each subrequest specify data that has technically not been committed yet. This means it is possible for some fields in a subresponse to be out of date by the time the entire composite request has been processed.
For example, suppose you have a composite request that includes several subrequests. The first subrequest POSTs an activity, and the subresponse for this subrequest includes a checksum value. When the composite request is actually committed to the database, the actual checksum value may differ from the one initially provided in the subresponse.
If a composite request is followed by a related request and the related request must have
the most up-to-date values, then the composite request must contain a
selections section that retrieves the required values. The GETs in the
selections section are always executed after all subrequests have been
committed.
Suppressing subresponse details
In some cases, a given object may be modified by multiple subrequests. This makes the intermediate subresponses unnecessary, and those subresponses can increase the size of the composite response unnecessarily and make the composite response harder to parse.
You can simplify the composite response by suppressing the amount of information returned for one or more subrequests. To do this, include the following with each relevant subrequest:
"includeResponse": false
For example:
{
"requests": [
{
"method": "post",
"uri": "/common/v1/activities/xc:202/notes",
"body": {
"data": {
"attributes": {
"body": "Cloud API note #1."
}
}
},
"includeResponse": false
},
...
The composite response still includes a subresponse for the subrequest. But instead of providing the endpoint's default response, the subresponse appears as:
{
"responseIncluded": false
},
The responseIncluded field defaults to true. If you want a detailed
response for a given subrequest, simply omit the responseIncluded
reference.
Using query parameters in subrequests
For a POST or PATCH subrequest, you can also refine which fields are returned. To do this, use the fields query parameter. The syntax for this is:
{
"requests": [
{
"method": "<post/patch>",
"uri": "<path>",
"body": {
"data": {
"attributes": {
"<field1>": "<value1>",
"<field2>": "<value2>",
...
}
}
},
"parameters" : {
"fields" : "<value>"
}
},
...
]
}
For example, the following code snippet creates an activity. For the subresponse, it specifies to include only the activity's id and the assigned user.
{
"requests": [
{
"method": "post",
"uri": "/claim/v1/claims/cc:34/activities",
"body": {
"data": {
"attributes": {
"activityPattern": "contact_insured",
"subject": "Cloud API activity"
}
}
},
"parameters" : {
"fields" : "id,assignedUser"
}
},
...
For a given API, you can see a complete list of all query parameters that can be used in
composite requests by executing a GET /openapi.json call. If a query
parameter is available to composite requests, the OpenAPI output will include the following
line: "x-gw-allowForCompositeApi": true.
The selections section
The selections section contains subselections that query for data. These are
executed after the subselections in the requests section (if any), and only if all the
subrequests commit data successfully.
The basic syntax for the selections section is shown below. You do not need
to specify a method for each subselection, as the only valid method in the
selections section is GET.
"selections": [
{
"uri": "<pathForFirstSubselection>"
},
{
"uri": "<pathForSecondSubselection>"
},
....
]
For example, the following code creates a new activity and a note for that activity. It then queries for the newly created activity.
{
"requests": [
{
"method": "post",
"uri": "/claim/v1/claims/cc:34/activities",
"body": {
"data": {
"attributes": {
"activityPattern": "contact_insured",
"subject": "Cloud API activity"
}
}
},
"vars": [
{
"name": "newActivityId",
"path": "$.data.attributes.id"
}
]
},
{
"method": "post",
"uri": "/common/v1/activities/${newActivityId}/notes",
"body": {
"data": {
"attributes": {
"body": "Cloud API note #1."
}
}
}
}
],
"selections": [
{
"uri": "/common/v1/activities/${newActivityId}"
}
]
}
For the complete syntax that includes all composite request features, see Complete composite request syntax.
Using query parameters in the selections section
You can use certain query parameters for each subselection. This includes:
fieldsfilterincludeTotalpageOffsetpageSizesort
Each subselection is independent from the others. You can use different query parameters for each subselection, and you can have some subselections with query parameters and others without query parameters.
The syntax for adding query parameters to a subselection is as follows:
"selections": [
{
"uri": "<pathForFirstQuery>",
"parameters" : {
"fields" : "<value>",
"filter" : [<value>],
"includeTotal" : <value>,
"pageOffset" : <value>,
"pageSize" : <value>,
"sort" : [<value>]
}
},
....
]
Note the following:
fieldsis specified as a single string of one or more fields, delimited by commas. The entire string is surrounded by quotes.- For example,
"assignedUser,dueDate,priority,subject"
- For example,
filterandsortare stringified arrays consisting of one or more expressions. Each individual expression is surrounded by quotes. The list of expressions is then surrounded by [ and ].- For example:
["dueDate:gt:2022-12-20","status:in:open,complete"]
- For example:
includeTotal,pageOffset, andpageSizeare either Boolean or integer values, and therefore do not use quotes.
For example, when querying for activities, to return only the assigned user, due date, priority and subject fields:
{
"uri": "/common/v1/activities",
"parameters" : {
"fields" : "assignedUser,dueDate,priority,subject"
}
To return only open and complete activities with due dates after 2022-12-20:
{
"uri": "/common/v1/activities",
"parameters" : {
"filter" : ["dueDate:gt:2022-12-20","status:in:open,complete"] }
To return activities based on multiple criteria:
{
"uri": "/common/v1/activities",
"parameters" : {
"fields" : "assignedUser,dueDate,priority,subject",
"filter" : ["dueDate:gt:2022-12-20","status:in:open,complete"],
"includeTotal" : true,
"pageSize" : 5,
"sort" : ["dueDate"]
}
There may be additional query parameters you can use. For information on how to determine whether a query parameter is supported in a composite request, see Composite request limitations.
Composite requests that execute only queries
You can create a composite request that does not create or modify data and instead only
queries for data. To do this, create a composite request with only a
selections section and no requests section. In this
case, the GETs in the selections section are always executed.
Responses to the selections subrequests
When a composite request contains a selections section, the response also
contains a selections section. This section has the same structure as the
responses section. It contains one subresponse for each subselection.
Every subresponse has three sections:
- A
bodysection, which by default contains the default response data defined in the corresponding endpoint. - A
headerssection, which contains any custom headers. - A
statusfield, which indicates the subresponse's status code.
Composite request examples
This documentation includes examples of composite requests for common business tasks. This includes the following:
- Creating a new claim with an unverified policy: Sample composite claim payload
- Creating, closing, and paying out a claim: Sample composite first-and-final