@@ -80,3 +80,86 @@ class Tag
8080This allows a parent resource to reference `Tag` objects in its relationships while `Tag` itself has
8181no public item endpoint. The `NotExposed` operation requires a `uriTemplate` with a single URI
8282variable.
83+
84+ # # Client-Generated IDs
85+
86+ The
87+ [JSON:API specification allows clients to supply their own `id` on `POST`](https://jsonapi.org/format/#crud-creating-client-ids)
88+ when the server agrees to accept it. This is useful when the client generates a UUID before sending
89+ the request and needs the server to persist it as-is.
90+
91+ By default, API Platform rejects client-supplied `data.id` on `POST` with a `400` response. Enable
92+ it explicitly when needed.
93+
94+ # ## Enabling Globally
95+
96+ **Symfony:**
97+
98+ ` ` ` yaml
99+ # config/packages/api_platform.yaml
100+ api_platform:
101+ jsonapi:
102+ allow_client_generated_id: true
103+ ` ` `
104+
105+ **Laravel** (`config/api-platform.php`):
106+
107+ ` ` ` php
108+ 'jsonapi' => [
109+ 'allow_client_generated_id' => true,
110+ ],
111+ ` ` `
112+
113+ # ## Enabling Per Operation
114+
115+ Use the `denormalizationContext` on the `#[Post]` operation to enable the feature for a single
116+ endpoint without affecting the rest of the API :
117+
118+ ` ` ` php
119+ <?php
120+
121+ namespace App\A piResource;
122+
123+ use ApiPlatform\J sonApi\S erializer\I temNormalizer;
124+ use ApiPlatform\M etadata\A piResource;
125+ use ApiPlatform\M etadata\G et;
126+ use ApiPlatform\M etadata\P ost;
127+
128+ #[ApiResource(
129+ formats: ['jsonapi' => ['application/vnd.api+json']],
130+ operations: [
131+ new Get(uriTemplate: '/books/{id}'),
132+ new Post(
133+ uriTemplate: '/books',
134+ denormalizationContext: [ItemNormalizer::ALLOW_CLIENT_GENERATED_ID => true],
135+ ),
136+ ],
137+ )]
138+ class Book
139+ {
140+ public ?string $id = null;
141+ public string $title = '';
142+ }
143+ ` ` `
144+
145+ A request that supplies `data.id` is then accepted :
146+
147+ ` ` ` http
148+ POST /api/books HTTP/1.1
149+ Accept: application/vnd.api+json
150+ Content-Type: application/vnd.api+json
151+
152+ {
153+ "data": {
154+ "type": "Book",
155+ "id": "01932b4c-a3f1-7b7e-9e5b-3d8f1c2e4a6d",
156+ "attributes": {
157+ "title": "Hyperion"
158+ }
159+ }
160+ }
161+ ` ` `
162+
163+ The supplied `id` is passed to the entity's `id` setter. The processor is responsible for persisting
164+ it. The response output schema still requires `id`; only the `POST` input schema marks it as
165+ optional.
0 commit comments