OpenAPI Specification Support (formerly Swagger)

API Platform natively support the OpenAPI API specification format.

API プラットフォームは、OpenAPI API 仕様形式をネイティブにサポートしています。

Screenshot

OpenAPI screencast
Watch the OpenAPI screencast

OpenAPI スクリーンキャストを見る

The specification of the API is available at the /docs.json path. By default, OpenAPI v3 is used. You can also get an OpenAPI v3-compliant version thanks to the spec_version query parameter: /docs.json?spec_version=3

API の仕様は、/docs.json パスで入手できます。デフォルトでは、OpenAPI v3 が使用されます。spec_version クエリ パラメータのおかげで、OpenAPI v3 準拠のバージョンを取得することもできます: /docs.json?spec_version=3

It also integrates a customized version of Swagger UI and ReDoc, some nice tools to display the API documentation in a user friendly way.

また、カスタマイズされたバージョンの Swagger UI と ReDoc (ユーザー フレンドリーな方法で API ドキュメントを表示するいくつかの優れたツール) を統合します。

Using the OpenAPI Command

You can also dump an OpenAPI specification for your API.

API の OpenAPI 仕様をダンプすることもできます。

OpenAPI, JSON format:

OpenAPI、JSON 形式:

docker compose exec php \
    bin/console api:openapi:export

OpenAPI, YAML format:

OpenAPI、YAML 形式:

docker compose exec php \
    bin/console api:openapi:export --yaml

Create a file containing the specification:

仕様を含むファイルを作成します。

docker compose exec php \
    bin/console api:openapi:export --output=swagger_docs.json

If you want to use the old OpenAPI v2 (Swagger) JSON format, use:

古い OpenAPI v2 (Swagger) JSON 形式を使用する場合は、次を使用します。

docker compose exec php \
    bin/console api:swagger:export

Overriding the OpenAPI Specification

Symfony allows to decorate services, here we need to decorate api_platform.openapi.factory.

symfony ではサービスを装飾できますが、ここでは api_platform.openapi.factory を装飾する必要があります。

In the following example, we will see how to override the title of the Swagger documentation and add a custom filter for the GET operation of /foos path.

次の例では、Swagger ドキュメントのタイトルを上書きし、/foos パスの GET 操作にカスタム フィルターを追加する方法を示します。

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

use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface;
use ApiPlatform\OpenApi\OpenApi;
use ApiPlatform\OpenApi\Model;

class OpenApiFactory implements OpenApiFactoryInterface
{
    private $decorated;

    public function __construct(OpenApiFactoryInterface $decorated)
    {
        $this->decorated = $decorated;
    }

    public function __invoke(array $context = []): OpenApi
    {
        $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');

        return $openApi;
    }
}

The impact on the swagger-ui is the following:

swagger-ui への影響は次のとおりです。

Swagger UI

Using the OpenAPI and Swagger Contexts

Sometimes you may want to change the information included in your OpenAPI documentation. The following configuration will give you total control over your OpenAPI definitions:

OpenAPI ドキュメントに含まれる情報を変更したい場合があります。次の構成により、OpenAPI 定義を完全に制御できます。

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/Product.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\ApiProperty;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity]
#[ApiResource]
class Product // The class name will be used to name exposed resources
{
    #[ORM\Id, ORM\Column, ORM\GeneratedValue]
    private ?int $id = null;

    /**
     * @param string $name A name property - this description will be available in the API documentation too.
     *
     */
    #[ORM\Column]
    #[Assert\NotBlank]
    #[ApiProperty(
        openapiContext: [
            'type' => 'string',
            'enum' => ['one', 'two'],
            'example' => 'one'
        ]
    )]
    public string $name;

    #[ORM\Column(type: "datetime")] 
    #[Assert\DateTime]
    #[ApiProperty(
        openapiContext: [
            'type' => 'string',
            'format' => 'date-time'
        ]
    )]
    public $timestamp;

    // ...
}
# api/config/api_platform/resources.yaml
resources:
    App\Entity\Product:
      properties:
        name:
          attributes:
            openapi_context:
              type: string
              enum: ['one', 'two']
              example: one
        timestamp:
          attributes:
            openapi_context:
              type: string
              format: date-time
<?xml version="1.0" encoding="UTF-8" ?>
<properties xmlns="https://api-platform.com/schema/metadata/properties-3.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="https://api-platform.com/schema/metadata/properties-3.0
           https://api-platform.com/schema/metadata/properties-3.0.xsd">
    <property resource="App\Entity\Product" name="name">
        <openapiContext>
            <values>
                <value name="type">type</value>
                <value name="enum">
                    <values>
                        <value>one</value>
                        <value>two</value>
                    </values>
                </value>
                <value name="example">one</value>
            </values>
        </openapiContext>
    </property>
    <property resource="App\Entity\Product" name="timestamp">
        <openapiContext>
            <values>
                <value name="type">string</value>
                <value name="format">date-time</value>
            </values>
        </openapiContext>
    </property>
</properties>

[/codeSelector]

[/コードセレクター]

This will produce the following Swagger documentation:

これにより、次の Swagger ドキュメントが生成されます。

"components": {
    "schemas": {
        "GrumpyPizza:jsonld": {
            "type": "object",
            "description": "",
            "properties": {
                "@context": {
                    "readOnly": true,
                    "type": "string"
                },
                "@id": {
                    "readOnly": true,
                    "type": "string"
                },
                "@type": {
                    "readOnly": true,
                    "type": "string"
                },
                "timestamp": {
                    "type": "string",
                    "format": "date-time"
                },
                "id": {
                    "readOnly": true,
                    "type": "integer"
                },
                "name": {
                    "type": "string",
                    "enum": [
                        "one",
                        "two"
                    ],
                    "example": "one"
                }
            }
        }
    }
}

To pass a context to the OpenAPI v2 generator, use the swaggerContext attribute (notice the prefix: swagger instead of openapi).

コンテキストを OpenAPI v2 ジェネレーターに渡すには、swaggerContext 属性を使用します (プレフィックス: openapi ではなく swagger に注意してください)。

Disabling an Operation From OpenAPI Documentation

Sometimes you may want to disable an operation from the OpenAPI documentation, for example to not exposing it. Using the openapi boolean option disables this operation from the OpenAPI documentation:

場合によっては、OpenAPI ドキュメントから操作を無効にしたい場合があります。たとえば、操作を公開しないようにする場合などです。openapi ブール値オプションを使用すると、OpenAPI ドキュメントからこの操作を無効にできます。

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/Product.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GetCollection;

#[ApiResource(
    operations: [
        new GetCollection(openapi: false)
    ]
)]
class Product
{
    // ...
}
# api/config/api_platform/resources.yaml
resources:
    App\Entity\Product:
        operations:
            ApiPlatform\Metadata\GetCollection:
                openapi: false
<?xml version="1.0" encoding="UTF-8" ?>
<!-- api/config/api_platform/resources.xml -->

<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
           https://api-platform.com/schema/metadata/resources-3.0.xsd">
    <resource class="App\Entity\Product">
        <operations>
            <operation class="ApiPlatform\Metadata\GetCollection" openapi="false" />
        </operations>
    </resource>
</resources>

[/codeSelector]

[/コードセレクター]

Note: as your route is not exposed, you may want to return a HTTP 404 if it's called. Prefer using the NotExposedAction controller instead.

注: ルートは公開されていないため、呼び出された場合は HTTP 404 を返したい場合があります。代わりに NotExposedAction コントローラーを使用することをお勧めします。

Changing the Name of a Definition

API Platform generates a definition name based on the serializer groups defined in the (de)normalizationContext. It's possible to override the name thanks to the swagger_definition_name option:

API プラットフォームは、(de)normalizationContext で定義されたシリアライザー グループに基づいて定義名を生成します。 swagger_definition_name オプションを使用すると、名前をオーバーライドできます。

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Post;

#[ApiResource]
#[Post(denormalizationContext: ['groups' => ['user:read'], 'swagger_definition_name' => 'Read'])]
class User
{
    // ...
}

It's also possible to re-use the (de)normalizationContext:

(de)normalizationContext を再利用することも可能です:

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Post;

#[ApiResource]
#[Post(denormalizationContext: [User::API_WRITE])]
class User
{
    const API_WRITE = [
        'groups' => ['user:read'],
        'swagger_definition_name' => 'Read',
    ];
}

Changing Operations in the OpenAPI Documentation

You also have full control over both built-in and custom operations documentation.

また、組み込み操作ドキュメントとカスタム操作ドキュメントの両方を完全に制御できます。

[codeSelector]

[コードセレクター]

<?php
// api/src/Entity/Rabbit.php
namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Post;
use App\Controller\RandomRabbit;

#[ApiResource]
#[Post(
    name: 'create_rabbit', 
    uriTemplate: '/rabbit/create', 
    controller: RandomRabbit::class, 
    openapiContext: [
        'summary' => 'Create a rabbit picture', 
        'description' => '# Pop a great rabbit picture by color!\n\n![A great rabbit](https://rabbit.org/graphics/fun/netbunnies/jellybean1-brennan1.jpg)', 
        'requestBody' => [
            'content' => [
                'application/json' => [
                    'schema' => [
                        'type' => 'object', 
                        'properties' => [
                            'name' => ['type' => 'string'], 
                            'description' => ['type' => 'string']
                        ]
                    ], 
                    'example' => [
                        'name' => 'Mr. Rabbit', 
                        'description' => 'Pink Rabbit'
                    ]
                ]
            ]
        ]
    ]
)]
class Rabbit
{
    // ...
}
resources:
  App\Entity\Rabbit:
    operations:
      create_rabbit:
        class: ApiPlatform\Metadata\Post
        path: '/rabbit/create'
        controller: App\Controller\RandomRabbit
        openapiContext:
          summary: Random rabbit picture
          description: >
            # Pop a great rabbit picture by color!

            ![A great rabbit](https://rabbit.org/graphics/fun/netbunnies/jellybean1-brennan1.jpg)

          requestBody:
            content:
              application/json:
                schema:
                  type: object
                  properties:
                    name: { type: string }
                    description: { type: string }
                example:
                  name: Mr. Rabbit
                  description: Pink rabbit

<?xml version="1.0" encoding="UTF-8" ?>
<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
        https://api-platform.com/schema/metadata/resources-3.0.xsd">
    <resource class="App\Entity\Rabbit">
        <operations>
            <operation class="ApiPlatform\Metadata\Post" name="create_rabbit" uriTemplate="/rabbit/create"
                       controller="App\Controller\RandomRabbit">
                <openapiContext>
                    <values>
                        <value name="summary">Create a rabbit picture </value>
                        <value name="description"># Pop a great rabbit picture by color!!

    ![A great rabbit](https://rabbit.org/graphics/fun/netbunnies/jellybean1-brennan1.jpg)</value>
                        <value name="content">
                            <values>
                                <value name="application/json">
                                    <values>
                                        <value name="schema">
                                            <values>
                                                <value name="type">object</value>
                                                <value name="properties">
                                                    <values>
                                                        <value name="name">
                                                            <values>
                                                                <value name="type">string</value>
                                                            </values>
                                                        </value>
                                                        <value name="description">
                                                            <values>
                                                                <value name="type">string</value>
                                                            </values>
                                                        </value>
                                                    </values>
                                                </value>
                                            </values>
                                        </value>
                                    </values>
                                </value>
                            </values>
                        </value>
                    </values>
                </openapiContext>
            </operation>
        </operations>
    </resource>
</resources>

[/codeSelector]

[/コードセレクター]

Impact on Swagger UI

Disabling Swagger UI or ReDoc

To disable Swagger UI (ReDoc will be shown by default):

Swagger UI を無効にするには (デフォルトで ReDoc が表示されます):

# api/config/packages/api_platform.yaml
api_platform:
    # ...
    enable_swagger_ui: false

To disable ReDoc:

ReDoc を無効にするには:

# api/config/packages/api_platform.yaml
api_platform:
    # ...
    enable_re_doc: false

Changing the Location of Swagger UI

By default, the Swagger UI is available at the API location (when the HTML format is asked) and at the route /docs.

デフォルトでは、Swagger UI は API の場所 (HTML 形式が要求された場合) およびルート /docs で使用できます。

You may want to change its route and/or disable it at the API location.

ルートを変更したり、API の場所で無効にしたりすることができます。

Changing the Route

Manually register the Swagger UI controller:

Swagger UI コントローラーを手動で登録します。

# app/config/routes.yaml
api_doc:
    path: /api_documentation
    controller: api_platform.swagger_ui.action

Change /api_documentation to the URI you wish Swagger UI to be accessible on.

/api_documentation を、Swagger UI にアクセスできるようにする URI に変更します。

Disabling Swagger UI at the API Location

To disable the Swagger UI at the API location, disable both Swagger UI and ReDoc:

API の場所で Swagger UI を無効にするには、Swagger UI と ReDoc の両方を無効にします。

# api/config/packages/api_platform.yaml
api_platform:
    # ...
    enable_swagger_ui: false
    enable_re_doc: false

If you have manually registered the Swagger UI controller, the Swagger UI will still be accessible at the route you have chosen.

Swagger UI コントローラーを手動で登録した場合でも、選択したルートで Swagger UI にアクセスできます。

Using a custom Asset Package in Swagger UI

Sometimes you may want to use a different Asset Package for the Swagger UI. In this way you'll have more fine-grained control over the asset URL generations. This is useful i.e. if you want to use different base path, base URL or asset versioning strategy.

場合によっては、Swagger UI に別のアセット パッケージを使用したい場合があります。このようにして、アセット URL の生成をより細かく制御できます。これは、別のベース パス、ベース URL、またはアセットを使用する場合などに便利です。バージョン管理戦略。

Specify a custom asset package name:

カスタム アセット パッケージ名を指定します。

# config/packages/api_platform.yaml
api_platform:
    asset_package: 'api_platform'

Set or override asset properties per package:

パッケージごとにアセット プロパティを設定またはオーバーライドします。

# config/packages/framework.yaml
framework:
    # ...
    assets:
        base_path: '/custom_base_path' # the default
        packages:
            api_platform:
                base_path: '/'

Overriding the UI Template

As described in the Symfony documentation, it's possible to override the Twig template that loads Swagger UI and renders the documentation:

Symfony のドキュメントで説明されているように、Swagger UI をロードしてドキュメントをレンダリングする Twig テンプレートをオーバーライドすることができます。

{# templates/bundles/ApiPlatformBundle/SwaggerUi/index.html.twig #}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>{% if title %}{{ title }} {% endif %}My custom template</title>
    {# ... #}
</html>

You may want to copy the one shipped with API Platform and customize it.

API Platform に同梱されているものをコピーしてカスタマイズすることもできます。

Compatibility Layer with Amazon API Gateway

AWS API Gateway supports OpenAPI partially, but it requires some changes. API Platform provides a way to be compatible with Amazon API Gateway.

AWS API Gateway は OpenAPI を部分的にサポートしていますが、いくつかの変更が必要です。API プラットフォームは、Amazon API Gateway と互換性を持つ方法を提供します。

To enable API Gateway compatibility on your OpenAPI docs, add api_gateway=true as query parameter: http://www.example.com/docs.json?api_gateway=true. The flag --api-gateway is also available through the command-line.

OpenAPI ドキュメントで API Gateway の互換性を有効にするには、クエリ パラメータとして api_gateway=true を追加します: http://www.example.com/docs.json?api_gateway=true.フラグ --api-gateway は、コマンドからも使用できます-ライン。

OAuth

If you implemented OAuth on your API, you should configure OpenApi's authorization using API Platform's configuration:

API に OAuth を実装した場合は、API プラットフォームの構成を使用して OpenApi の承認を構成する必要があります。

api_platform:
    oauth:
        # To enable or disable OAuth.
        enabled: false

        # The OAuth client ID.
        clientId: ''

        # The OAuth client secret.
        clientSecret: ''

        # The OAuth type.
        type: 'oauth2'

        # The OAuth flow grant type.
        flow: 'application'

        # The OAuth token url.
        tokenUrl: '/oauth/v2/token'

        # The OAuth authentication url.
        authorizationUrl: '/oauth/v2/auth'

        # The OAuth scopes.
        scopes: []

Note that clientId and clientSecret are being used by the SwaggerUI if enabled.

clientId と clientSecret が有効になっている場合、SwaggerUI によって使用されていることに注意してください。

Configure the OAuth Scopes Option

The api_platform.oauth.scopes option requires an array value with the scopes name and description. For example:

api_platform.oauth.scopes オプションには、スコープの名前と説明を含む配列値が必要です。例えば:

api_platform:
    oauth:
        scopes:
            profile: "This scope value requests access to the End-User's default profile Claims, which are: name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at."
            email: "This scope value requests access to the email and email_verified Claims."
            address: "This scope value requests access to the address Claim."
            phone: "This scope value requests access to the phone_number and phone_number_verified Claims."

Note: if you're using an OpenID Connect server (such as Keycloak or Auth0), the openid scope must be set according to the OpenID Connect specification.

注: OpenID Connect サーバー (Keycloak や Auth0 など) を使用している場合は、OpenID Connect 仕様に従って openid スコープを設定する必要があります。

Info Object

The info object provides metadata about the API like licensing information or a contact. You can specify this information using API Platform's configuration:

info オブジェクトは、ライセンス情報や連絡先など、API に関するメタデータを提供します。この情報は、API プラットフォームの構成を使用して指定できます。

api_platform:

    # The title of the API.
    title: 'API title'

    # The description of the API.
    description: 'API description'

    # The version of the API.
    version: '0.0.0'

    openapi:
        # The contact information for the exposed API.
        contact:
            # The identifying name of the contact person/organization.
            name:
            # The URL pointing to the contact information. MUST be in the format of a URL.
            url:
            # The email address of the contact person/organization. MUST be in the format of an email address.
            email:
        # A URL to the Terms of Service for the API. MUST be in the format of a URL.
        termsOfService:
        # The license information for the exposed API.
        license:
            # The license name used for the API.
            name:
            # URL to the license used for the API. MUST be in the format of a URL.
            url: