Skip to content

Commit ebc27d9

Browse files
committed
docs: metadata mutators
1 parent 263c804 commit ebc27d9

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

core/extending.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ The following tables summarizes which extension point to use depending on what y
2020
| [Messenger Handlers](../symfony/messenger.md) | create 100% custom, RPC, async, service-oriented endpoints (should be used in place of custom controllers because the messenger integration is compatible with both REST and GraphQL, while custom controllers only work with REST) |
2121
| [DTOs](dto.md) | use a specific class to represent the input or output data structure related to an operation |
2222
| [Kernel Events](events.md) | customize the HTTP request or response (REST only, other extension points must be preferred when possible) |
23+
| [Operations and Resources](operations.md) | use mutators to dynamically alter metadata (works for third party API endpoints) |
2324

2425
## Doctrine Specific Extension Points
2526

core/operations.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,3 +589,76 @@ class Weather
589589
```
590590

591591
That's it!
592+
593+
## Customize Operation and Resource Metadata
594+
595+
Metadata mutators allow a dynamic control over resources and operations, by programmatically altering metadata before they are exposed as endpoints. Providing a way to modify, add or remove operations, adjust serialization groups or pagination settings.
596+
597+
It also makes it possible to customize built-in endpoints from a third-party API, such as Sylius.
598+
599+
### Resource Mutator
600+
601+
Use the resource mutator to modify the entire resource metadata by adding the attribute and target resource class as argument:
602+
603+
```php
604+
<?php
605+
// src/Entity/Book.php
606+
namespace App;
607+
608+
use ApiPlatform\Metadata\ApiResource;
609+
use ApiPlatform\Metadata\AsResourceMutator;
610+
use ApiPlatform\Metadata\ResourceMutatorInterface;
611+
use App\Entity\User;
612+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
613+
614+
#[AsResourceMutator(resourceClass: Book::class)]
615+
final readonly class UserApiDomainMutator implements ResourceMutatorInterface
616+
{
617+
// .env
618+
// API_PREFIX="/library"
619+
public function __construct(#[Autowire(env: 'API_PREFIX')] private string $apiDomain) {
620+
}
621+
622+
public function __invoke(ApiResource $resource): ApiResource
623+
{
624+
if (!$operations = $resource->getOperations()) {
625+
return $resource;
626+
}
627+
628+
foreach ($operations as $name => $operation) {
629+
// add route prefix to each resource operation
630+
$prefixedOperation = $operation->withRoutePrefix($this->apiDomain);
631+
$operations->add($name, $prefixedOperation);
632+
}
633+
634+
return $resource->withOperations($operations);
635+
}
636+
}
637+
```
638+
639+
### Operation Mutator
640+
641+
The operation mutator will modify a specific operation's metadata, by using the attribute and passing the operation name:
642+
643+
```php
644+
<?php
645+
646+
namespace App\Mutator;
647+
648+
use ApiPlatform\Metadata\AsOperationMutator;
649+
use ApiPlatform\Metadata\Operation;
650+
use ApiPlatform\Metadata\OperationMutatorInterface;
651+
652+
#[AsOperationMutator(operationName: '_api_Book_get_collection')]
653+
final class BookOperationMutator implements OperationMutatorInterface
654+
{
655+
public function __invoke(Operation $operation): Operation
656+
{
657+
$context = $operation->getNormalizationContext() ?? [];
658+
// add another group to normalization group
659+
$context['groups'][] = 'review:list:read';
660+
661+
return $operation->withNormalizationContext($context);
662+
}
663+
}
664+
```

0 commit comments

Comments
 (0)