Skip to content

Commit 17d371c

Browse files
authored
docs(openapi): refacto override OpenAPI section (#2207)
1 parent 0f90473 commit 17d371c

File tree

1 file changed

+39
-59
lines changed

1 file changed

+39
-59
lines changed

core/openapi.md

Lines changed: 39 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,17 @@ To produce a specification including only the operation matching your tag.
6969

7070
## Overriding the OpenAPI Specification
7171

72-
### Overriding the OpenAPI Specification with Symfony
73-
74-
Symfony allows to [decorate services](https://symfony.com/doc/current/service_container/service_decoration.html), here we
75-
need to decorate `api_platform.openapi.factory`.
72+
API Platform generates the OpenAPI specification through the `ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface` service.
73+
To customize it, you need to create your own factory service that **decorates** (wraps) the original one.
7674

7775
In the following example, we will see how to override the title and the base path URL of the Swagger documentation and add a custom filter for
78-
the `GET` operation of `/foos` path.
76+
the `GET` operation of `/api/grumpy_pizzas/{id}` path.
7977

80-
```yaml
81-
# api/config/services.yaml
82-
App\OpenApi\OpenApiFactory:
83-
decorates: 'api_platform.openapi.factory'
84-
arguments: ['@App\OpenApi\OpenApiFactory.inner']
85-
autoconfigure: false
86-
```
78+
First, create a custom OpenAPI factory that decorates the original service:
8779

8880
```php
8981
<?php
82+
9083
namespace App\OpenApi;
9184

9285
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
@@ -125,74 +118,61 @@ class OpenApiFactory implements OpenApiFactoryInterface
125118
}
126119
```
127120

128-
The impact on the swagger-ui is the following:
129-
130-
![Swagger UI](images/swagger-ui-modified.png)
121+
Then configure it as a decorator in your service container:
131122

132-
### Overriding the OpenAPI Specification with Laravel
123+
### Decorate with Symfony
133124

134-
Laravel allows to [decorate services](https://laravel.com/docs/container#extending-bindings), here we
135-
need to decorate `api_platform.openapi.factory`.
125+
Symfony allows to [decorate services](https://symfony.com/doc/current/service_container/service_decoration.html) as following:
136126

137-
In the following example, we will see how to override the title and the base path URL of the Swagger documentation and add a custom filter for
138-
the `GET` operation of `/foos` path.
127+
<code-selector>
139128

140129
```php
141130
<?php
142131

143-
namespace App\Providers;
132+
namespace App\OpenApi;
144133

145-
use Illuminate\Support\ServiceProvider;
146134
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
147-
use App\OpenApi\OpenApiFactory;
135+
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
148136

149-
class AppServiceProvider extends ServiceProvider
137+
#[AsDecorator(decorates: 'api_platform.openapi.factory')]
138+
class OpenApiFactory implements OpenApiFactoryInterface
150139
{
151-
public function register(): void
152-
{
153-
$this->app->extend(OpenApiFactoryInterface::class, function (OpenApiFactoryInterface $factory) {
154-
return new OpenApiFactory($factory);
155-
});
156-
}
140+
// ...
157141
}
158142
```
159143

144+
```yaml
145+
# api/config/services.yaml
146+
services:
147+
# ...
148+
App\OpenApi\OpenApiFactory:
149+
decorates: 'api_platform.openapi.factory'
150+
arguments: ['@App\OpenApi\OpenApiFactory.inner']
151+
autoconfigure: false
152+
```
153+
154+
</code-selector>
155+
156+
### Decorate with Laravel
157+
158+
Laravel allows to [decorate services](https://laravel.com/docs/container#extending-bindings), as following:
159+
160160
```php
161161
<?php
162-
namespace App\OpenApi;
162+
#
163+
namespace App\Providers;
163164

165+
use Illuminate\Support\ServiceProvider;
164166
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
165-
use ApiPlatform\OpenApi\OpenApi;
166-
use ApiPlatform\OpenApi\Model;
167+
use App\OpenApi\OpenApiFactory;
167168

168-
class OpenApiFactory implements OpenApiFactoryInterface
169+
class AppServiceProvider extends ServiceProvider
169170
{
170-
171-
public function __construct(private OpenApiFactoryInterface $decorated)
172-
{
173-
}
174-
175-
public function __invoke(array $context = []): OpenApi
171+
public function register(): void
176172
{
177-
$openApi = $this->decorated->__invoke($context);
178-
$pathItem = $openApi->getPaths()->getPath('/api/grumpy_pizzas/{id}');
179-
$operation = $pathItem->getGet();
180-
181-
$openApi->getPaths()->addPath('/api/grumpy_pizzas/{id}', $pathItem->withGet(
182-
$operation->withParameters(array_merge(
183-
$operation->getParameters(),
184-
[new Model\Parameter('fields', 'query', 'Fields to remove of the output')]
185-
))
186-
));
187-
188-
$openApi = $openApi->withInfo((new Model\Info('New Title', 'v2', 'Description of my custom API'))->withExtensionProperty('info-key', 'Info value'));
189-
$openApi = $openApi->withExtensionProperty('key', 'Custom x-key value');
190-
$openApi = $openApi->withExtensionProperty('x-value', 'Custom x-value value');
191-
192-
// to define base path URL
193-
$openApi = $openApi->withServers([new Model\Server('https://foo.bar')]);
194-
195-
return $openApi;
173+
$this->app->extend(OpenApiFactoryInterface::class, function (OpenApiFactoryInterface $factory) {
174+
return new OpenApiFactory($factory);
175+
});
196176
}
197177
}
198178
```

0 commit comments

Comments
 (0)