You may need to create or update related resources at the same time as the primary resource — for example, when creating a complex object in a single API request. The JSON:API specification does not cover this case. OroPlatform’s solution is to use the included section of the JSON request body.
When creating a primary resource, include new related resources in the included section. Reference them from the primary resource using temporary identifiers (such as UUIDs or any unique string within the request scope).
Request
POST /api/accounts HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
Request body
{
"data": {
"type": "accounts",
"id": "1",
"attributes": {
"name": "Cloth World"
},
"relationships": {
"organization": {
"data": {"type": "organizations", "id": "1"}
},
"owner": {
"data": {"type": "users", "id": "1"}
},
"contacts": {
"data": [
{"type": "contacts", "id": "8da4d8e7-6b25-4c5c-8075-b510f7bbb84f"},
{"type": "contacts", "id": "707dda0d-35f5-47b9-b2ce-a3e92b9fdee7"}
]
},
"defaultContact": {
"data": {"type": "contacts", "id": "707dda0d-35f5-47b9-b2ce-a3e92b9fdee7"}
}
}
},
"included": [
{
"type": "contacts",
"id": "8da4d8e7-6b25-4c5c-8075-b510f7bbb84f",
"attributes": {
"firstName": "John",
"lastName": "Doe"
},
"relationships": {
"organization": {
"data": {"type": "organizations", "id": "1"}
},
"owner": {
"data": {"type": "users", "id": "1"}
},
"source": {
"data": {"type": "contactsources", "id": "tv"}
}
}
},
{
"type": "contacts",
"id": "707dda0d-35f5-47b9-b2ce-a3e92b9fdee7",
"attributes": {
"firstName": "Nancy",
"lastName": "Jones"
},
"relationships": {
"organization": {
"data": {"type": "organizations", "id": "1"}
},
"owner": {
"data": {"type": "users", "id": "1"}
}
}
}
]
}
This request:
- Creates the account Cloth World.
- Creates two contacts, John Doe and Nancy Jones.
- Assigns both contacts to the account.
- Makes Nancy Jones the default contact.
Response
{
"data": {
"type": "accounts",
"id": "52",
"attributes": {
"name": "Cloth World"
},
"relationships": {
"contacts": {
"data": [
{"type": "contacts", "id": "79"},
{"type": "contacts", "id": "80"}
]
},
"defaultContact": {
"data": {"type": "contacts", "id": "80"}
}
}
},
"included": [
{
"type": "contacts",
"id": "79",
"meta": {
"includeId": "8da4d8e7-6b25-4c5c-8075-b510f7bbb84f"
},
"attributes": {
"firstName": "John",
"lastName": "Doe"
}
},
{
"type": "contacts",
"id": "80",
"meta": {
"includeId": "707dda0d-35f5-47b9-b2ce-a3e92b9fdee7"
},
"attributes": {
"firstName": "Nancy",
"lastName": "Jones"
}
}
]
}
The temporary identifiers specified in the request are returned in the includeId meta attribute in the response. Use this to match resources between the request and response.Identifiers can be any unique string within the request scope — GUIDs, simple strings like john_doe, etc.
To update related resources in the same request, mark them with the update meta property set to true.
Request
PATCH /api/accounts/52 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
Request body
{
"data": {
"type": "accounts",
"id": "52",
"attributes": {
"name": "Cloth World Market"
},
"relationships": {
"defaultContact": {
"data": {"type": "contacts", "id": "79"}
}
}
},
"included": [
{
"meta": {
"update": true
},
"type": "contacts",
"id": "79",
"attributes": {
"primaryEmail": "[email protected]"
}
}
]
}
This request:
- Renames the account to Cloth World Market.
- Sets the primary email for contact
79 and makes them the default contact.
Specifying relationships between resources
All included resources must be connected to the primary resource. You can specify the connection in either direction — these two examples are equivalent:
From primary to included:
{
"data": {
"type": "accounts",
"id": "52",
"relationships": {
"contact": {
"data": {"type": "contacts", "id": "79"}
}
}
},
"included": [
{
"meta": {"update": true},
"type": "contacts",
"id": "79",
"attributes": {
"primaryEmail": "[email protected]"
}
}
]
}
From included to primary:
{
"data": {
"type": "accounts",
"id": "52"
},
"included": [
{
"meta": {"update": true},
"type": "contacts",
"id": "79",
"attributes": {
"primaryEmail": "[email protected]"
},
"relationships": {
"account": {
"data": {"type": "accounts", "id": "52"}
}
}
}
]
}