Skip to content

Commit b76f3d5

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

File tree

2 files changed

+66
-63
lines changed

2 files changed

+66
-63
lines changed

core/operations.md

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,16 @@ 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. 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}`. 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.
195+
196+
## Configuring Operations
197+
198+
The URL, the method and the default status code (among other options) can be configured per operation.
199+
200+
In the next example, both `GET` and `POST` operations are registered with custom URLs. Those will override the URLs generated by default.
201+
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`:
193202

194203
<code-selector>
195204

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

201-
use ApiPlatform\Action\NotFoundAction;
202-
use ApiPlatform\Metadata\Get;
203-
use ApiPlatform\Metadata\GetCollection;
204210
use ApiPlatform\Metadata\ApiResource;
211+
use ApiPlatform\Metadata\Get;
212+
use ApiPlatform\Metadata\Post;
205213

206214
#[ApiResource(operations: [
207215
new Get(
208-
controller: NotFoundAction::class,
209-
read: false,
210-
output: false
216+
uriTemplate: '/grimoire/{id}',
217+
requirements: ['id' => '\d+'],
218+
defaults: ['color' => 'brown'],
219+
options: ['my_option' => 'my_option_value'],
220+
schemes: ['https'],
221+
host: '{subdomain}.api-platform.com'
211222
),
212-
new GetCollection()
223+
new Post(
224+
uriTemplate: '/grimoire',
225+
status: 301
226+
)
213227
])]
214228
class Book
215229
{
216-
// ...
230+
//...
217231
}
218232
```
219233

@@ -222,11 +236,19 @@ class Book
222236
resources:
223237
App\Entity\Book:
224238
operations:
225-
ApiPlatform\Metadata\GetCollection: ~
239+
ApiPlatform\Metadata\Post:
240+
uriTemplate: '/grimoire'
241+
status: 301
226242
ApiPlatform\Metadata\Get:
227-
controller: ApiPlatform\Action\NotFoundAction
228-
read: false
229-
output: false
243+
uriTemplate: '/grimoire/{id}'
244+
requirements:
245+
id: '\d+'
246+
defaults:
247+
color: 'brown'
248+
host: '{subdomain}.api-platform.com'
249+
schemes: ['https']
250+
options:
251+
my_option: 'my_option_value'
230252
```
231253
232254
```xml
@@ -239,22 +261,33 @@ resources:
239261
https://api-platform.com/schema/metadata/resources-3.0.xsd">
240262
<resource class="App\Entity\Book">
241263
<operations>
242-
<operation class="ApiPlatform\Metadata\GetCollection" />
243-
<operation class="ApiPlatform\Metadata\Get" controller="ApiPlatform\Action\NotFoundAction"
244-
read="false" output="false" />
264+
<operation class="ApiPlatform\Metadata\Post" uriTemplate="/grimoire" status="301" />
265+
<operation class="ApiPlatform\Metadata\Get" uriTemplate="/grimoire/{id}" host="{subdomain}.api-platform.com">
266+
<requirements>
267+
<requirement property="id">\d+</requirement>
268+
</requirements>
269+
<defaults>
270+
<values>
271+
<value name="color">brown</value>
272+
</values>
273+
</defaults>
274+
<schemes>
275+
<scheme>https</scheme>
276+
</schemes>
277+
<options>
278+
<values>
279+
<value name="color">brown</value>
280+
</values>
281+
</options>
282+
</operation>
245283
</operations>
246284
</resource>
247285
</resources>
248286
```
249287

250288
</code-selector>
251289

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`:
290+
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:
258291

259292
<code-selector>
260293

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

299+
use ApiPlatform\Action\NotFoundAction;
266300
use ApiPlatform\Metadata\ApiResource;
267301
use ApiPlatform\Metadata\Get;
268302
use ApiPlatform\Metadata\Post;
269303

270304
#[ApiResource(operations: [
271305
new Get(
272306
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'
307+
controller: NotFoundAction::class,
308+
read: false,
309+
output: false
278310
),
279311
new Post(
280312
uriTemplate: '/grimoire',
@@ -283,7 +315,7 @@ use ApiPlatform\Metadata\Post;
283315
])]
284316
class Book
285317
{
286-
//...
318+
// ...
287319
}
288320
```
289321

@@ -297,14 +329,9 @@ resources:
297329
status: 301
298330
ApiPlatform\Metadata\Get:
299331
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'
332+
controller: ApiPlatform\Action\NotFoundAction
333+
read: false
334+
output: false
308335
```
309336
310337
```xml
@@ -318,24 +345,8 @@ resources:
318345
<resource class="App\Entity\Book">
319346
<operations>
320347
<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>
348+
<operation class="ApiPlatform\Metadata\Get" uriTemplate="/grimoire/{id}"
349+
controller="ApiPlatform\Action\NotFoundAction" read="false" output="false" />
339350
</operations>
340351
</resource>
341352
</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)