Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 39 additions & 59 deletions core/openapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,17 @@ To produce a specification including only the operation matching your tag.

## Overriding the OpenAPI Specification

### Overriding the OpenAPI Specification with Symfony

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

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
the `GET` operation of `/foos` path.
the `GET` operation of `/api/grumpy_pizzas/{id}` path.

```yaml
# api/config/services.yaml
App\OpenApi\OpenApiFactory:
decorates: 'api_platform.openapi.factory'
arguments: ['@App\OpenApi\OpenApiFactory.inner']
autoconfigure: false
```
First, create a custom OpenAPI factory that decorates the original service:

```php
<?php

namespace App\OpenApi;

use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
Expand Down Expand Up @@ -125,74 +118,61 @@ class OpenApiFactory implements OpenApiFactoryInterface
}
```

The impact on the swagger-ui is the following:

![Swagger UI](images/swagger-ui-modified.png)
Then configure it as a decorator in your service container:

### Overriding the OpenAPI Specification with Laravel
### Decorate with Symfony

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

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
the `GET` operation of `/foos` path.
<code-selector>

```php
<?php

namespace App\Providers;
namespace App\OpenApi;

use Illuminate\Support\ServiceProvider;
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
use App\OpenApi\OpenApiFactory;
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;

class AppServiceProvider extends ServiceProvider
#[AsDecorator(decorates: 'api_platform.openapi.factory')]
class OpenApiFactory implements OpenApiFactoryInterface
{
public function register(): void
{
$this->app->extend(OpenApiFactoryInterface::class, function (OpenApiFactoryInterface $factory) {
return new OpenApiFactory($factory);
});
}
// ...
}
```

```yaml
# api/config/services.yaml
services:
# ...
App\OpenApi\OpenApiFactory:
decorates: 'api_platform.openapi.factory'
arguments: ['@App\OpenApi\OpenApiFactory.inner']
autoconfigure: false
```

</code-selector>

### Decorate with Laravel

Laravel allows to [decorate services](https://laravel.com/docs/container#extending-bindings), as following:

```php
<?php
namespace App\OpenApi;
#
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
use ApiPlatform\OpenApi\OpenApi;
use ApiPlatform\OpenApi\Model;
use App\OpenApi\OpenApiFactory;

class OpenApiFactory implements OpenApiFactoryInterface
class AppServiceProvider extends ServiceProvider
{

public function __construct(private OpenApiFactoryInterface $decorated)
{
}

public function __invoke(array $context = []): OpenApi
public function register(): void
{
$openApi = $this->decorated->__invoke($context);
$pathItem = $openApi->getPaths()->getPath('/api/grumpy_pizzas/{id}');
$operation = $pathItem->getGet();

$openApi->getPaths()->addPath('/api/grumpy_pizzas/{id}', $pathItem->withGet(
$operation->withParameters(array_merge(
$operation->getParameters(),
[new Model\Parameter('fields', 'query', 'Fields to remove of the output')]
))
));

$openApi = $openApi->withInfo((new Model\Info('New Title', 'v2', 'Description of my custom API'))->withExtensionProperty('info-key', 'Info value'));
$openApi = $openApi->withExtensionProperty('key', 'Custom x-key value');
$openApi = $openApi->withExtensionProperty('x-value', 'Custom x-value value');

// to define base path URL
$openApi = $openApi->withServers([new Model\Server('https://foo.bar')]);

return $openApi;
$this->app->extend(OpenApiFactoryInterface::class, function (OpenApiFactoryInterface $factory) {
return new OpenApiFactory($factory);
});
}
}
```
Expand Down