Skip to content

Commit fbf8a02

Browse files
committed
docs(core/operations): update explanation about omitting GET item operation
1 parent 0f90473 commit fbf8a02

File tree

2 files changed

+68
-63
lines changed

2 files changed

+68
-63
lines changed

core/operations.md

Lines changed: 67 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,18 @@ resources:
189189
API Platform is smart enough to automatically register the applicable Symfony route referencing a built-in CRUD action
190190
just by specifying the method name as key, or by checking the explicitly configured HTTP method.
191191

192-
If you do not want to allow access to the resource item (i.e. you don't want a `GET` item operation), instead of omitting it altogether, you should instead declare a `GET` item operation which returns HTTP 404 (Not Found), so that the resource item can still be identified by an IRI. For example:
192+
By default, API Platform uses the first `Get` operation defined to generate the IRI of an item and the first `GetCollection` operation to generate the IRI of a collection.
193+
194+
If your resource does not have any `Get` operation, API Platform automatically adds an operation to help generating this IRI.
195+
If your resource has any identifier, this operation will look like `/books/{id}`. But if your resource doesn’t have any identifier, API Platform will use the Skolem format `/.well-known/genid/{id}`.
196+
Those routes are not exposed from any documentation (for instance OpenAPI), but are anyway declared on the routing system and always return a HTTP 404.
197+
198+
## Configuring Operations
199+
200+
The URL, the method and the default status code (among other options) can be configured per operation.
201+
202+
In the next example, both `GET` and `POST` operations are registered with custom URLs. Those will override the URLs generated by default.
203+
In addition to that, we require the `id` parameter in the URL of the `GET` operation to be an integer, and we configure the status code generated after successful `POST` request to be `301`:
193204

194205
<code-selector>
195206

@@ -198,22 +209,27 @@ If you do not want to allow access to the resource item (i.e. you don't want a `
198209
// api/src/Entity/Book.php
199210
namespace App\Entity;
200211

201-
use ApiPlatform\Action\NotFoundAction;
202-
use ApiPlatform\Metadata\Get;
203-
use ApiPlatform\Metadata\GetCollection;
204212
use ApiPlatform\Metadata\ApiResource;
213+
use ApiPlatform\Metadata\Get;
214+
use ApiPlatform\Metadata\Post;
205215

206216
#[ApiResource(operations: [
207217
new Get(
208-
controller: NotFoundAction::class,
209-
read: false,
210-
output: false
218+
uriTemplate: '/grimoire/{id}',
219+
requirements: ['id' => '\d+'],
220+
defaults: ['color' => 'brown'],
221+
options: ['my_option' => 'my_option_value'],
222+
schemes: ['https'],
223+
host: '{subdomain}.api-platform.com'
211224
),
212-
new GetCollection()
225+
new Post(
226+
uriTemplate: '/grimoire',
227+
status: 301
228+
)
213229
])]
214230
class Book
215231
{
216-
// ...
232+
//...
217233
}
218234
```
219235

@@ -222,11 +238,19 @@ class Book
222238
resources:
223239
App\Entity\Book:
224240
operations:
225-
ApiPlatform\Metadata\GetCollection: ~
241+
ApiPlatform\Metadata\Post:
242+
uriTemplate: '/grimoire'
243+
status: 301
226244
ApiPlatform\Metadata\Get:
227-
controller: ApiPlatform\Action\NotFoundAction
228-
read: false
229-
output: false
245+
uriTemplate: '/grimoire/{id}'
246+
requirements:
247+
id: '\d+'
248+
defaults:
249+
color: 'brown'
250+
host: '{subdomain}.api-platform.com'
251+
schemes: ['https']
252+
options:
253+
my_option: 'my_option_value'
230254
```
231255
232256
```xml
@@ -239,22 +263,33 @@ resources:
239263
https://api-platform.com/schema/metadata/resources-3.0.xsd">
240264
<resource class="App\Entity\Book">
241265
<operations>
242-
<operation class="ApiPlatform\Metadata\GetCollection" />
243-
<operation class="ApiPlatform\Metadata\Get" controller="ApiPlatform\Action\NotFoundAction"
244-
read="false" output="false" />
266+
<operation class="ApiPlatform\Metadata\Post" uriTemplate="/grimoire" status="301" />
267+
<operation class="ApiPlatform\Metadata\Get" uriTemplate="/grimoire/{id}" host="{subdomain}.api-platform.com">
268+
<requirements>
269+
<requirement property="id">\d+</requirement>
270+
</requirements>
271+
<defaults>
272+
<values>
273+
<value name="color">brown</value>
274+
</values>
275+
</defaults>
276+
<schemes>
277+
<scheme>https</scheme>
278+
</schemes>
279+
<options>
280+
<values>
281+
<value name="color">brown</value>
282+
</values>
283+
</options>
284+
</operation>
245285
</operations>
246286
</resource>
247287
</resources>
248288
```
249289

250290
</code-selector>
251291

252-
## Configuring Operations
253-
254-
The URL, the method and the default status code (among other options) can be configured per operation.
255-
256-
In the next example, both `GET` and `POST` operations are registered with custom URLs. Those will override the URLs generated by default.
257-
In addition to that, we require the `id` parameter in the URL of the `GET` operation to be an integer, and we configure the status code generated after successful `POST` request to be `301`:
292+
When you do not want to allow access to the resource item (i.e. you don't want a `GET` item operation), instead of omitting the resource item altogether, you can explicitly specify the IRI of the resource item by declaring a `GET` item operation that returns HTTP 404 (Not Found). For example:
258293

259294
<code-selector>
260295

@@ -263,18 +298,17 @@ In addition to that, we require the `id` parameter in the URL of the `GET` opera
263298
// api/src/Entity/Book.php
264299
namespace App\Entity;
265300

301+
use ApiPlatform\Action\NotFoundAction;
266302
use ApiPlatform\Metadata\ApiResource;
267303
use ApiPlatform\Metadata\Get;
268304
use ApiPlatform\Metadata\Post;
269305

270306
#[ApiResource(operations: [
271307
new Get(
272308
uriTemplate: '/grimoire/{id}',
273-
requirements: ['id' => '\d+'],
274-
defaults: ['color' => 'brown'],
275-
options: ['my_option' => 'my_option_value'],
276-
schemes: ['https'],
277-
host: '{subdomain}.api-platform.com'
309+
controller: NotFoundAction::class,
310+
read: false,
311+
output: false
278312
),
279313
new Post(
280314
uriTemplate: '/grimoire',
@@ -283,7 +317,7 @@ use ApiPlatform\Metadata\Post;
283317
])]
284318
class Book
285319
{
286-
//...
320+
// ...
287321
}
288322
```
289323

@@ -297,14 +331,9 @@ resources:
297331
status: 301
298332
ApiPlatform\Metadata\Get:
299333
uriTemplate: '/grimoire/{id}'
300-
requirements:
301-
id: '\d+'
302-
defaults:
303-
color: 'brown'
304-
host: '{subdomain}.api-platform.com'
305-
schemes: ['https']
306-
options:
307-
my_option: 'my_option_value'
334+
controller: ApiPlatform\Action\NotFoundAction
335+
read: false
336+
output: false
308337
```
309338
310339
```xml
@@ -318,24 +347,8 @@ resources:
318347
<resource class="App\Entity\Book">
319348
<operations>
320349
<operation class="ApiPlatform\Metadata\Post" uriTemplate="/grimoire" status="301" />
321-
<operation class="ApiPlatform\Metadata\Get" uriTemplate="/grimoire/{id}" host="{subdomain}.api-platform.com">
322-
<requirements>
323-
<requirement property="id">\d+</requirement>
324-
</requirements>
325-
<defaults>
326-
<values>
327-
<value name="color">brown</value>
328-
</values>
329-
</defaults>
330-
<schemes>
331-
<scheme>https</scheme>
332-
</schemes>
333-
<options>
334-
<values>
335-
<value name="color">brown</value>
336-
</values>
337-
</options>
338-
</operation>
350+
<operation class="ApiPlatform\Metadata\Get" uriTemplate="/grimoire/{id}"
351+
controller="ApiPlatform\Action\NotFoundAction" read="false" output="false" />
339352
</operations>
340353
</resource>
341354
</resources>

symfony/messenger.md

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,10 @@ namespace App\Entity;
2828

2929
use ApiPlatform\Metadata\ApiResource;
3030
use ApiPlatform\Metadata\ApiProperty;
31-
use ApiPlatform\Metadata\Get;
3231
use ApiPlatform\Metadata\Post;
3332
use Symfony\Component\Validator\Constraints as Assert;
34-
use ApiPlatform\Action\NotFoundAction;
3533

3634
#[ApiResource(operations: [
37-
new Get(controller: NotFoundAction::class, read: false, status: 404),
3835
new Post(messenger: true, output: false, status: 202)
3936
])]
4037
final class Person
@@ -56,18 +53,13 @@ resources:
5653
status: 202
5754
messenger: true
5855
output: false
59-
ApiPlatform\Metadata\Get:
60-
status: 404
61-
controller: ApiPlatform\Action\NotFoundAction
62-
read: false
6356
```
6457
6558
</code-selector>
6659
6760
Because the `messenger` attribute is `true`, when a `POST` is handled by API Platform, the corresponding instance of the `Person` will be dispatched.
6861

69-
For this example, only the `POST` operation is enabled. We disabled the item operation using the `NotFoundAction`. A resource must have at least one item operation as it must be identified by an IRI, here the route `/people/1` exists, eventhough it returns a 404 status code.
70-
We use the `status` attribute to configure API Platform to return a [202 Accepted HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202).
62+
For this example, only the `POST` operation is enabled. If the resource does not have any `Get` operation, API Platform [automatically adds an operation to help generating an IRI identify the resource](../core/operations/#enabling-and-disabling-operations). We use the `status` attribute to configure API Platform to return a [202 Accepted HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202).
7163
It indicates that the request has been received and will be treated later, without giving an immediate return to the client.
7264
Finally, the `output` attribute is set to `false`, so the HTTP response that will be generated by API Platform will be empty, and the [serialization process](../core/serialization.md) will be skipped.
7365

0 commit comments

Comments
 (0)