Skip to content

Commit 0d7e614

Browse files
committed
Add documentation on system providers and processors
This commit introduces detailed documentation on the workflow of state providers and processors in the system. It includes a schema, examples of decorating providers and processors, and specific implementations for both Symfony and Laravel frameworks.
1 parent f121b17 commit 0d7e614

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

core/extending.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,119 @@ For instance, if you want to send a mail after a resource has been persisted, bu
3636
To replace existing API Platform services with your decorators, [check out how to decorate services](https://symfony.com/doc/current/service_container/service_decoration.html).
3737

3838
<p align="center" class="symfonycasts"><a href="https://symfonycasts.com/screencast/api-platform-security/service-decoration?cid=apip"><img src="../symfony/images/symfonycasts-player.png" alt="Service Decoration screencast"><br>Watch the Service Decoration screencast</a></p>
39+
40+
## System providers and processors
41+
42+
The system is based on a workflow composed of **state providers** and **state processors**
43+
44+
The schema below describes them:
45+
46+
```mermaid
47+
---
48+
title: System providers and processors
49+
---
50+
flowchart TB
51+
C1(ReadProvider) --> C2(AccessCheckerProvider)
52+
C2 --> C3(DeserializeProvider)
53+
C3 --> C4(ParameterProvider)
54+
C4 --> C5(ValidateProcessor)
55+
C5 --> C6(WriteProcessor)
56+
C6 --> C7(SerializeProcessor)
57+
```
58+
59+
### Symfony Access Checker Provider
60+
61+
When using Symfony, the access checker provider is used at three different stages:
62+
- `api_platform.state_provider.access_checker.post_validate` decorates the ValidateProvider
63+
- `api_platform.state_provider.access_checker.post_deserialize` decorates the DeserializeProvider
64+
- `api_platform.state_provider.access_checker` decorates the ReadProvider
65+
66+
67+
### Decoration example
68+
69+
Here is an example of the decoration of the RespondProcessor:
70+
71+
Starts by creating your `CustomRespondProcessor`:
72+
```php
73+
<?php
74+
namespace App\State;
75+
76+
use ApiPlatform\State\ProcessorInterface;
77+
78+
final class CustomRespondProcessor implements ProcessorInterface
79+
{
80+
public function __construct(private readonly ProcessorInterface $processor){}
81+
82+
public function __invoke($data, string $resourceClass, string $operationName, array $context)
83+
{
84+
// You can add pre-write code here.
85+
86+
// Call the decorated write stage (this syntax calls the __invoke method).
87+
$writtenObject = ($this->processor)($data, $resourceClass, $operationName, $context);
88+
89+
// You can add post-write code here.
90+
91+
return $writtenObject;
92+
}
93+
}
94+
```
95+
96+
Now you should decorate the RespondProcessor with the CustomRespondProcessor using Symfony or Laravel:
97+
98+
### Decorating the RespondProcessor with Symfony
99+
100+
With Symfony you can simply do that by adding the `#[AsDecorator]` attribute as following:
101+
102+
```php
103+
namespace App\State;
104+
105+
use ApiPlatform\State\ProcessorInterface;
106+
107+
#[AsDecorator(decorates: 'api_platform.state.processor.respond_processor',)]
108+
final class CustomRespondProcessor implements ProcessorInterface
109+
{
110+
// ...
111+
}
112+
```
113+
114+
or in the `services.yaml` by defining:
115+
116+
```yaml
117+
# api/config/services.yaml
118+
services:
119+
# ...
120+
App\State\CustomRespondProcessor:
121+
decorates: api_platform.state.processor.respond_processor
122+
```
123+
124+
And that's it!
125+
126+
### Decorating the RespondProcessor with Laravel
127+
```php
128+
<?php
129+
130+
namespace App\Providers;
131+
132+
use App\State\CustomRespondProcessor;
133+
use ApiPlatform\State\Processor\RespondProcessor;
134+
use Illuminate\Contracts\Foundation\Application;
135+
use Illuminate\Support\ServiceProvider;
136+
137+
class AppServiceProvider extends ServiceProvider
138+
{
139+
public function register(): void
140+
{
141+
$this->app->singleton(CustomRespondProcessor::class, function (Application $app) {
142+
return new CustomRespondProcessor();
143+
});
144+
145+
$this->app->extend(RespondProcessor::class, function (RespondProcessor $respondProcessor, Application $app) {
146+
return new CustomRespondProcessor($respondProcessor);
147+
});
148+
}
149+
150+
public function boot(): void
151+
{
152+
}
153+
}
154+
```

0 commit comments

Comments
 (0)