Skip to content

Commit a967c21

Browse files
Explain itemUriTemplate option (#1592)
* docs: explain itemUriTemplate option * Apply suggestions from code review Co-authored-by: Alan Poulain <contact@alanpoulain.eu> Co-authored-by: Alan Poulain <contact@alanpoulain.eu>
1 parent fb52adb commit a967c21

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

core/getting-started.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ resources:
183183
<?xml version="1.0" encoding="UTF-8" ?>
184184
<!-- api/config/api_platform/resources.xml -->
185185

186-
<resource xmlns="https://api-platform.com/schema/metadata/resources-3.0"
186+
<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
187187
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
188188
xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
189189
https://api-platform.com/schema/metadata/resources-3.0.xsd">
@@ -196,7 +196,7 @@ resources:
196196
<types>
197197
<type>https://schema.org/Offer</type> <!-- optional -->
198198
</types>
199-
</resource>
199+
</resources>
200200
</resources>
201201
```
202202

core/operations.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,100 @@ book_post_publication:
440440
_api_operation_name: post_publication
441441
```
442442
443+
## Defining Which Operation to Use to Generate the IRI
444+
445+
Using multiple operations on your resource, you may want to specify which operation to use to generate the IRI, instead
446+
of letting API Platform use the first one it finds.
447+
448+
Let's say you have 2 resources in relationship: `Company` and `User`, where a company has multiple users. You can declare
449+
the following routes:
450+
451+
- `/users`
452+
- `/users/{id}`
453+
- `/companies/{companyId}/users`
454+
- `/companies/{companyId}/users/{id}`
455+
456+
The first routes (`/users...`) are only accessible by the admin, and the others by regular users. Calling
457+
`/companies/{companyId}/users` should return IRIs matching `/companies/{companyId}/users/{id}` to not expose an admin
458+
route to regular users.
459+
460+
To do so, use the `itemUriTemplate` option only available on `GetCollection` and `Post` operations:
461+
462+
[codeSelector]
463+
464+
```php
465+
<?php
466+
// api/src/Entity/Book.php
467+
namespace App\Entity;
468+
469+
use ApiPlatform\Metadata\ApiResource;
470+
use ApiPlatform\Metadata\Get;
471+
use ApiPlatform\Metadata\GetCollection;
472+
use ApiPlatform\Metadata\Post;
473+
474+
#[GetCollection] // auto-generated path will be /users
475+
#[Get] // auto-generated path will be /users/{id}
476+
#[GetCollection(uriTemplate: '/companies/{companyId}/users', itemUriTemplate: '/companies/{companyId}/users/{id}'/*, ... */)]
477+
#[Post(uriTemplate: '/companies/{companyId}/users', itemUriTemplate: '/companies/{companyId}/users/{id}'/*, ... */)]
478+
#[Get(uriTemplate: '/companies/{companyId}/users/{id}'/*, ... */)]
479+
class User
480+
{
481+
//...
482+
}
483+
```
484+
485+
```yaml
486+
# api/config/api_platform/resources.yaml
487+
resources:
488+
App\Entity\Book:
489+
- operations:
490+
ApiPlatform\Metadata\GetCollection: ~
491+
ApiPlatform\Metadata\Get: ~
492+
- operations:
493+
ApiPlatform\Metadata\GetCollection:
494+
uriTemplate: /companies/{companyId}/users
495+
itemUriTemplate: /companies/{companyId}/users/{id}
496+
# ...
497+
ApiPlatform\Metadata\Post:
498+
uriTemplate: /companies/{companyId}/users
499+
itemUriTemplate: /companies/{companyId}/users/{id}
500+
# ...
501+
ApiPlatform\Metadata\Get:
502+
uriTemplate: /companies/{companyId}/users/{id}
503+
# ...
504+
```
505+
506+
```xml
507+
<?xml version="1.0" encoding="UTF-8" ?>
508+
<!-- api/config/api_platform/resources.xml -->
509+
510+
<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
511+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
512+
xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
513+
https://api-platform.com/schema/metadata/resources-3.0.xsd">
514+
<resource class="App\Entity\Book">
515+
<operations>
516+
<operation class="ApiPlatform\Metadata\GetCollection" />
517+
<operation class="ApiPlatform\Metadata\Get" />
518+
</operations>
519+
</resource>
520+
521+
<resource class="App\Entity\Book">
522+
<operations>
523+
<operation class="ApiPlatform\Metadata\GetCollection" uriTemplate="/companies/{companyId}/users" itemUriTemplate="/companies/{companyId}/users/{id}" />
524+
<operation class="ApiPlatform\Metadata\Post" uriTemplate="/companies/{companyId}/users" itemUriTemplate="/companies/{companyId}/users/{id}" />
525+
<operation class="ApiPlatform\Metadata\Get" uriTemplate="/companies/{companyId}/users/{id}" />
526+
</operations>
527+
</resource>
528+
</resources>
529+
```
530+
531+
[/codeSelector]
532+
533+
API Platform will find the operation matching this `itemUriTemplate` and use it to generate the IRI.
534+
535+
If this option is not set, the first `Get` operation is used to generate the IRI.
536+
443537
## Expose a Model Without Any Routes
444538

445539
Sometimes, you may want to expose a model, but want it to be used through subrequests only, and never through item or collection operations.

0 commit comments

Comments
 (0)