Skip to content

Commit beffaf2

Browse files
committed
doc: jsonapi
1 parent fbb6c32 commit beffaf2

2 files changed

Lines changed: 120 additions & 0 deletions

File tree

core/jsonapi.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# JSON:API
2+
3+
API Platform supports the [JSON:API](https://jsonapi.org) format. When a client
4+
sends a request with an `Accept: application/vnd.api+json` header, API Platform
5+
serializes responses following the JSON:API specification.
6+
7+
For details on enabling formats, see
8+
[content negotiation](content-negotiation.md).
9+
10+
## Entity Identifiers as Resource IDs
11+
12+
By default, API Platform uses IRIs (Internationalized Resource Identifiers) as
13+
the `id` field of JSON:API resource objects. For example, a `Dummy` resource with
14+
database ID `10` has `"id": "/dummies/10"` in the JSON:API response.
15+
16+
The JSON:API specification requires the `id` field to be a string that, combined
17+
with `type`, uniquely identifies a resource. Using IRIs as IDs is valid, but some
18+
clients expect plain entity identifiers (such as `"10"`) and use the `links.self`
19+
field for navigation.
20+
21+
To use entity identifiers instead of IRIs, set `use_iri_as_id` to `false`:
22+
23+
```yaml
24+
# config/packages/api_platform.yaml
25+
api_platform:
26+
jsonapi:
27+
use_iri_as_id: false
28+
```
29+
30+
### Behavior Changes
31+
32+
When `use_iri_as_id` is `false`:
33+
34+
- **Resource `id`**: Uses the entity identifier (e.g., `"10"`) instead of the IRI
35+
(e.g., `"/dummies/10"`).
36+
- **`links.self`**: Added to each resource object, pointing to the IRI.
37+
- **Relationships**: Related resources are referenced by entity identifier and
38+
`type` instead of IRI and `type`.
39+
40+
### Default Behavior (`use_iri_as_id: true`)
41+
42+
```json
43+
{
44+
"data": {
45+
"id": "/dummies/10",
46+
"type": "Dummy",
47+
"attributes": {
48+
"name": "Dummy #10"
49+
},
50+
"relationships": {
51+
"relatedDummy": {
52+
"data": {
53+
"id": "/related_dummies/1",
54+
"type": "RelatedDummy"
55+
}
56+
}
57+
}
58+
}
59+
}
60+
```
61+
62+
### Entity Identifier Mode (`use_iri_as_id: false`)
63+
64+
```json
65+
{
66+
"data": {
67+
"id": "10",
68+
"type": "Dummy",
69+
"links": {
70+
"self": "/dummies/10"
71+
},
72+
"attributes": {
73+
"name": "Dummy #10"
74+
},
75+
"relationships": {
76+
"relatedDummy": {
77+
"data": {
78+
"id": "1",
79+
"type": "RelatedDummy"
80+
}
81+
}
82+
}
83+
}
84+
}
85+
```
86+
87+
### Composite Identifiers
88+
89+
Resources with composite identifiers use a semicolon-separated string as the `id`
90+
value (e.g., `"field1=val1;field2=val2"`).
91+
92+
### Resources Without a Standalone Item Endpoint
93+
94+
When using entity identifier mode, API Platform must resolve the IRI for any
95+
resource that appears in a relationship. If a resource has no standalone `GET` item
96+
endpoint (for example, it is only exposed as a subresource), IRI resolution fails.
97+
98+
Use the `NotExposed` operation to register a URI template for internal IRI
99+
resolution without exposing a public endpoint. A `NotExposed` operation registers
100+
the route internally but returns a `404` response when accessed directly:
101+
102+
```php
103+
<?php
104+
105+
namespace App\Entity;
106+
107+
use ApiPlatform\Metadata\NotExposed;
108+
109+
#[NotExposed(uriTemplate: '/tags/{id}')]
110+
class Tag
111+
{
112+
public int $id;
113+
public string $label;
114+
}
115+
```
116+
117+
This allows a parent resource to reference `Tag` objects in its relationships
118+
while `Tag` itself has no public item endpoint. The `NotExposed` operation
119+
requires a `uriTemplate` with a single URI variable.

outline.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ chapters:
4747
- validation
4848
- security
4949
- content-negotiation
50+
- jsonapi
5051
- pagination
5152
- deprecations
5253
- default-order

0 commit comments

Comments
 (0)