Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update graphql, events & extending docs for Laravel and v4 #2026

Open
wants to merge 13 commits into
base: 4.0
Choose a base branch
from
9 changes: 6 additions & 3 deletions core/events.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# The Event System

In API Platform 3.2 you may need `event_listeners_backward_compatibility_layer: true` to keep event listeners activated.
> [!WARNING]
> In API Platform 4.0 with Symfony, you need `use_symfony_listeners: true` to activate event listeners.

Note: using Kernel event with API Platform should be mostly limited to tweaking the generated HTTP response. Also, GraphQL is **not supported**.
[For most use cases, better extension points, working both with REST and GraphQL, are available](extending.md).
---

> [!NOTE]
> Using Kernel event with API Platform should be mostly limited to tweaking the generated HTTP response. Also, GraphQL is **not supported**.

API Platform Core implements the [Action-Domain-Responder](https://github.com/pmjones/adr) pattern. This implementation
is covered in depth in the [Creating custom operations and controllers](operations.md#creating-custom-operations-and-controllers)
Expand Down
117 changes: 117 additions & 0 deletions core/extending.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,120 @@ For instance, if you want to send a mail after a resource has been persisted, bu
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).

<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>

## System Providers and Processors

The system is based on a workflow composed of **state providers** and **state processors**

The schema below describes them:

```mermaid
---
title: System providers and processors
---
flowchart TB
C1(ReadProvider) --> C2(AccessCheckerProvider)
C2 --> C3(DeserializeProvider)
C3 --> C4(ParameterProvider)
C4 --> C5(ValidateProcessor)
C5 --> C6(WriteProcessor)
C6 --> C7(SerializeProcessor)
```

### Symfony Access Checker Provider

When using Symfony, the access checker provider is used at three different stages:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only for rest I think

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this one, do you want to add somewhere that it's only for REST?

- `api_platform.state_provider.access_checker.post_validate` decorates the `ValidateProvider`
- `api_platform.state_provider.access_checker.post_deserialize` decorates the `DeserializeProvider`
- `api_platform.state_provider.access_checker` decorates the `ReadProvider`


### Decoration Example

Here is an example of the decoration of the RespondProcessor:

Starts by creating your `CustomRespondProcessor`:

```php
<?php
namespace App\State;

use ApiPlatform\State\ProcessorInterface;

final class CustomRespondProcessor implements ProcessorInterface
{
public function __construct(private readonly ProcessorInterface $processor) {}

public function __invoke($data, string $resourceClass, string $operationName, array $context)
vinceAmstoutz marked this conversation as resolved.
Show resolved Hide resolved
{
// You can add pre-write code here.

// Call the decorated write stage (this syntax calls the __invoke method).
$writtenObject = ($this->processor)($data, $resourceClass, $operationName, $context);

// You can add post-write code here.

return $writtenObject;
}
}
```

Now you should decorate the RespondProcessor with the CustomRespondProcessor using Symfony or Laravel:

### Decorating the RespondProcessor with Symfony

With Symfony you can simply do that by adding the `#[AsDecorator]` attribute as following:

```php
namespace App\State;

use ApiPlatform\State\ProcessorInterface;

#[AsDecorator(decorates: 'api_platform.state.processor.respond_processor',)]
final class CustomRespondProcessor implements ProcessorInterface
{
// ...
}
```

or in the `services.yaml` by defining:

```yaml
# api/config/services.yaml
services:
# ...
App\State\CustomRespondProcessor:
decorates: api_platform.state.processor.respond_processor
```

And that's it!

### Decorating the RespondProcessor with Laravel
```php
<?php

namespace App\Providers;

use App\State\CustomRespondProcessor;
use ApiPlatform\State\Processor\RespondProcessor;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(CustomRespondProcessor::class, function (Application $app) {
return new CustomRespondProcessor();
});
vinceAmstoutz marked this conversation as resolved.
Show resolved Hide resolved

$this->app->extend(RespondProcessor::class, function (RespondProcessor $respondProcessor, Application $app) {
vinceAmstoutz marked this conversation as resolved.
Show resolved Hide resolved
return new CustomRespondProcessor($respondProcessor);
});
}

public function boot(): void
{
}
}
```
Loading