### Manually install assets with assets:install --symlink Source: https://symfony.com/bundles/NelmioApiDocBundle/current/faq.html Run this command to manually install NelmioApiDocBundle assets if the composer post-install-cmd or post-update-cmd event does not trigger the ScriptHandler::installAssets script, which can cause 404 or 406 HTTP status errors on css, js, and image files. ```bash $ php bin/console assets:install --symlink ``` -------------------------------- ### Inline documentation output example Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/type_describer.html Example of the resulting schema when the describer chain is stopped, showing the property documented inline. ```json { "Money": { "type": "object", "properties": { "cents": { "type": "integer" }, "currency": { "type": "string", "example": "USD", "description": "A currency code represented as a string." } } } } ``` -------------------------------- ### Install NelmioApiDocBundle via Composer Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Execute this command in your project directory to download the latest version of the bundle. ```bash $ composer require nelmio/api-doc-bundle ``` -------------------------------- ### Complete example: UserController implementation Source: https://symfony.com/bundles/NelmioApiDocBundle/current/symfony_attributes.html A controller demonstrating the usage of MapQueryString, MapQueryParameter, MapRequestPayload, and MapUploadedFile with OpenAPI attributes. ```php namespace AppBundle\Controller; use AppBundle\UserDTO; use AppBundle\UserQuery; use OpenApi\Attributes as OA; use Symfony\Component\HttpKernel\Attribute\MapQueryParameter; use Symfony\Component\HttpKernel\Attribute\MapQueryString; use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\HttpKernel\Attribute\MapUploadedFile; use Symfony\Component\Routing\Attribute\Route; class UserController { /** * Find user with MapQueryString. */ #[Route('/api/users', methods: ['GET'])] #[OA\Parameter( name: 'userId', description: 'Id of the user to find', in: 'query', )] public function findUser(#[MapQueryString] UserQuery $userQuery) { // ... } /** * Find user with MapQueryParameter. */ #[Route('/api/users/v2', methods: ['GET'])] #[OA\Parameter( name: 'userId', description: 'Id of the user to find', in: 'query', )] public function findUserV2(#[MapQueryParameter] int $userId) { // ... } /** * Create a new user. */ #[Route('/api/users', methods: ['POST'])] #[OA\RequestBody( groups: ['create'], )] public function createUser(#[MapRequestPayload] UserDTO $user) { // ... } /** * Upload a profile picture */ #[Route('/api/users/picture', methods: ['POST'])] #[OA\RequestBody( description: 'Content of the profile picture upload request', content: [ new OA\MediaType('multipart/form-data', new OA\Schema( properties: [new OA\Property( property: 'file', description: 'File containing the profile picture', )], )), ], )] public function createUser(#[MapUploadedFile] UploadedFile $picture) { // ... } } ``` -------------------------------- ### Configure models and aliases Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Example configuration for models, including JMS Serializer usage and custom model aliasing. ```yaml nelmio_api_doc: # ... models: use_jms: false names: - # Alias the class 'App\Foo' to 'FooPrivate' for the 'private' group alias: 'FooPrivate' type: 'App\Foo' groups: - 'private' ``` -------------------------------- ### Complete example: UserQuery DTO Source: https://symfony.com/bundles/NelmioApiDocBundle/current/symfony_attributes.html A simple DTO class used for query parameters. ```php class UserQuery { public int $userId; } ``` -------------------------------- ### Example default configuration for nelmio_api_doc Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Shows the default configuration structure for the NelmioApiDocBundle. Includes options for type_info, validation groups, operation ID generation, caching, documentation, media types, HTML config, areas, and models. ```yaml # Example default configuration nelmio_api_doc: # Whether to use the symfony/type-info component for determining types. type_info: false # If true, `groups` passed to #[Model] attributes will be used to limit validation constraints use_validation_groups: false # Defines how to generate operation ids operation_id_generation: always_prepend cache: # define cache pool to use pool: null # define cache item id item_id: null # The documentation to use as base documentation: # Example: # info: # title: 'My App' # description: 'My App Description' # List of enabled Media Types media_types: - json # UI configuration options html_config: assets_mode: cdn # https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ swagger_ui_config: [] # https://redocly.com/docs/redoc/config/ redocly_config: [] # https://scalar.com/products/api-references/configuration scalar_config: [] # https://docs.stoplight.io/docs/elements/b074dc47b2826-elements-configuration-options stoplight_config: [] # Filter the routes that are documented areas: default: path_patterns: # Examples: # - ^/api # - '^/api(?!/admin)' host_patterns: # Example: # - ^api\. name_patterns: # Example: # - ^api_v1 # whether to filter by attributes with_attribute: false security: # Authentication schemes https://swagger.io/docs/specification/v3_0/authentication/ MyBearerScheme: type: 'http' scheme: 'bearer' # if set disables default routes without attributes disable_default_routes: false # The base documentation used for the area documentation: # Example: # info: # title: 'My App' # description: 'My App Description' cache: # define cache pool to use for the area pool: null # define cache item id for the area item_id: null models: use_jms: false names: - alias: ~ # Example: 'Foo' type: ~ # Example: 'App\Foo' groups: null options: null serializationContext: [] areas: [] ``` -------------------------------- ### Configure NelmioApiDocBundle in YAML Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Example configuration for the bundle, typically located in config/packages/nelmio_api_doc.yaml. It defines servers, info, and security schemes. ```yaml nelmio_api_doc: documentation: servers: - url: http://api.example.com/unsafe description: API over HTTP - url: https://api.example.com/secured description: API over HTTPS info: title: My App description: This is an awesome app! version: 1.0.0 x-build: #CommitHash components: securitySchemes: Bearer: type: http scheme: bearer bearerFormat: JWT security: - Bearer: [] ``` -------------------------------- ### Configure areas in NelmioApiDocBundle Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Example configuration for the areas dictionary, including path, host, and name patterns, as well as security and documentation settings. ```yaml nelmio_api_doc: # ... areas: default: path_patterns: # Examples: # - ^/api # - '^/api(?!/admin)' host_patterns: # Example: # - ^api\. name_patterns: # Example: # - ^api_v1 with_attribute: false security: MyBearerScheme: type: 'http' scheme: 'bearer' disable_default_routes: false documentation: # Example: # info: # title: 'My App' # description: 'My App Description' cache: # define cache pool to use for the area pool: null # define cache item id for the area item_id: null ``` -------------------------------- ### Configure security schemes for an area Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Example of defining a security scheme within an area configuration. ```yaml nelmio_api_doc: # ... areas: default: security: MyBearerScheme: type: 'http' scheme: 'bearer' ``` -------------------------------- ### Basic Area Configuration Source: https://symfony.com/bundles/NelmioApiDocBundle/current/areas.html Example of basic area filtering using path, host, and name patterns. ```yaml nelmio_api_doc: areas: path_patterns: [ ^/api ] host_patterns: [ ^api\. ] name_patterns: [ ^api_v1 ] ``` -------------------------------- ### JMS Serializer virtual property example Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html An example of a virtual property using JMS Serializer annotations. ```php /** * A nested serializer property with no context group * * @JMS\VirtualProperty * @JMS\Type('ArrayCollection') * @JMS\Since('1.0') * * @return Collection|ItemResponse[] */ public function getItems(): Collection|array { return $this->items; } ``` -------------------------------- ### Define Currency Value Object Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/type_describer.html Example of a custom Currency value object that requires custom documentation representation. ```php namespace App\ValueObject; class Currency { public string $code; public string $symbol; } ``` -------------------------------- ### Complete example: UserDto with validation Source: https://symfony.com/bundles/NelmioApiDocBundle/current/symfony_attributes.html A DTO class utilizing Symfony Serializer groups and Validator constraints. ```php use Symfony\Component\Serializer\Attribute\Groups; use Symfony\Component\Validator\Constraints as Assert; class UserDto { #[Groups(["default", "create", "update"])] #[Assert\NotBlank(groups: ["default", "create"])] public string $username; } ``` -------------------------------- ### Configure Security for Default Area Source: https://symfony.com/bundles/NelmioApiDocBundle/current/security.html Example of security configuration for the default area, which adds the ApiKeyAuth security scheme to all registered paths. ```yaml nelmio_api_doc: # ... areas: default: security: ApiKeyAuth: type: 'apiKey' name: 'X-API-Key' in: 'header' ``` -------------------------------- ### Define Money Entity Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/type_describer.html Example of an entity using the custom Currency value object. ```php namespace App\Entity; use App\ValueObject\Currency; class Money { public int $cents; public Currency $currency; } ``` -------------------------------- ### Controller action with optional path parameter Source: https://symfony.com/bundles/NelmioApiDocBundle/current/faq.html An example of a controller action using an optional path parameter that results in the parameter being marked as required in Swagger UI. ```php /** * Get all user meta or metadata for a specific field. * * @Route("/{user}/meta/{metaName}", * methods={"GET"}, * name="get_user_metadata" * ) * * @OA\Response( * response=200, * description="Json object with all user meta data or a json string with the value of the requested field" * ) */ public function getAction(string $user, string $metaName = null) { ... } ``` -------------------------------- ### Custom Model Describer for Money class Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html Implements ModelDescriberInterface to describe a Money entity as a string with example and description. The supports method checks that the model type is an ObjectType and the class is Money. ```php namespace App\ModelDescriber; use App\Entity\Money; use Nelmio\ApiDocBundle\Model\Model; use Nelmio\ApiDocBundle\ModelDescriber\ModelDescriberInterface; use OpenApi\Annotations\Schema; use Symfony\Component\TypeInfo\Type\ObjectType; class MoneyModelDescriber implements ModelDescriberInterface { public function describe(Model $model, Schema $schema): void { $schema->type = 'string'; $schema->example = '12.34 EUR'; $schema->description = 'A monetary value represented as a string.'; } public function supports(Model $model): bool { $type = $model->getTypeInfo(); if (!$type instanceof ObjectType) { return false; } return Money::class === $type->getClassName(); } } ``` -------------------------------- ### Define Enum for Model Decoration Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html Example enum used to demonstrate custom model describer decoration. ```php namespace App\Entity; enum Status: string { case ACTIVE = 'active'; case INACTIVE = 'inactive'; case PENDING = 'pending'; } ``` -------------------------------- ### Money value object class Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html Example value object that you may want to represent as a string with a specific format in your API documentation. ```php namespace App\Entity; class Money { public int $cents; public string $currency; } ``` -------------------------------- ### Override Twig template to customize Swagger UI Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/ui.html Create `templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig` to override the default template. The example adds custom styles and scripts, and shows how to change Swagger UI and Redocly configurations. Note the exclamation mark in `{% extends '@!NelmioApiDoc/SwaggerUi/index.html.twig' %}` to avoid a 'reached nested level' error. ```twig {# templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig #} {# To avoid a "reached nested level" error an exclamation mark `!` has to be added See https://symfony.com/blog/new-in-symfony-3-4-improved-the-overriding-of-templates #} {% extends '@!NelmioApiDoc/SwaggerUi/index.html.twig' %} {# Change Swagger UI configuration All parameters are explained on Swagger UI website: https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ #} {% block swagger_initialization %} {% endblock %} {# Change Redocly configuration All parameters are explained on Redocly website: https://redocly.com/docs/redoc/config/ #} {% block swagger_initialization %} {% endblock %} {# Import your own stylesheet #} {% block stylesheets %} {{ parent() }} {% endblock stylesheets %} {# Import your own script #} {% block javascripts %} {{ parent() }} {% endblock javascripts %} ``` -------------------------------- ### Configure base documentation Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Provide base OpenAPI/Swagger documentation information. ```yaml nelmio_api_doc: # ... documentation: # Any valid OpenAPI/Swagger documentation info: title: 'My App' description: 'My App Description' ``` -------------------------------- ### Generate static HTML documentation Source: https://symfony.com/bundles/NelmioApiDocBundle/current/commands.html Generates a static HTML version of the API documentation using the `--format=html` option. ```bash $ php bin/console nelmio:apidoc:dump --format=html > api.html ``` -------------------------------- ### Configure Documentation UI Routes in PHP Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Define the JSON and UI routes in config/routes/nelmio_api_doc.php using the routing configurator. ```php // config/routes/nelmio_api_doc.php use Symfony outing outer outingconfigurator; return static function (RoutingConfigurator $routes): void { $routes->add('app.swagger', '/api/doc.json') ->controller('nelmio_api_doc.controller.swagger') ->methods(['GET']); // Uncomment one of the following to enable a documentation UI: $routes->add('app.swagger_ui', '/api/doc') ->controller('nelmio_api_doc.controller.swagger_ui') ->methods(['GET']); // $routes->add('app.redocly', '/api/doc') // ->controller('nelmio_api_doc.controller.redocly') // ->methods(['GET']); // $routes->add('app.stoplight', '/api/doc') // ->controller('nelmio_api_doc.controller.stoplight') // ->methods(['GET']); // $routes->add('app.scalar', '/api/doc') // ->controller('nelmio_api_doc.controller.scalar') // ->methods(['GET']); }; ``` -------------------------------- ### Configure Documentation UI Routes in YAML Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Define the JSON and UI routes in config/routes/nelmio_api_doc.yaml. Uncomment the desired UI controller to enable it. ```yaml # config/routes/nelmio_api_doc.yaml app.swagger: path: /api/doc.json methods: GET defaults: { _controller: nelmio_api_doc.controller.swagger } # Uncomment one of the following to enable a documentation UI: app.swagger_ui: path: /api/doc methods: GET defaults: { _controller: nelmio_api_doc.controller.swagger_ui } # app.redocly: # path: /api/doc # methods: GET # defaults: { _controller: nelmio_api_doc.controller.redocly } # app.stoplight: # path: /api/doc # methods: GET # defaults: { _controller: nelmio_api_doc.controller.stoplight } # app.scalar: # path: /api/doc # methods: GET # defaults: { _controller: nelmio_api_doc.controller.scalar } ``` -------------------------------- ### Generate HTML with custom configuration Source: https://symfony.com/bundles/NelmioApiDocBundle/current/commands.html Generates HTML documentation with custom configuration using `--html-config`, including offline assets, server URL, and disabling the sandbox via Swagger UI config. ```bash $ php bin/console nelmio:apidoc:dump --format=html --html-config '{"assets_mode":"offline","server_url":"https://example.com","swagger_ui_config":{"supportedSubmitMethods":[]}}' > api.html ``` -------------------------------- ### Configure UI settings Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Set UI configuration options including assets mode and specific tool configurations. ```yaml nelmio_api_doc: # ... html_config: assets_mode: 'cdn' # https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ swagger_ui_config: [] # https://redocly.com/docs/redoc/config/ redocly_config: [] # https://docs.stoplight.io/docs/elements/b074dc47b2826-elements-configuration-options stoplight_config: [] ``` -------------------------------- ### Generate JSON with and without pretty formatting Source: https://symfony.com/bundles/NelmioApiDocBundle/current/commands.html Shows how to generate pretty-printed JSON (default) and minified JSON using the `--no-pretty` option. ```bash $ php bin/console nelmio:apidoc:dump --format=json > json-pretty-formatted.json $ php bin/console nelmio:apidoc:dump --format=json --no-pretty > json-no-pretty.json ``` -------------------------------- ### Force documentation regeneration with kernel.reset Source: https://symfony.com/bundles/NelmioApiDocBundle/current/frankenphp.html Tag the generator with kernel.reset in services.yaml to regenerate the documentation on every request instead of keeping it in memory. ```yaml # config/services.yaml services: nelmio_api_doc.generator.default: tags: - { name: kernel.reset, method: reset } ``` -------------------------------- ### Configure cache settings Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Define the cache pool and item ID for the generated documentation. ```yaml nelmio_api_doc: # ... cache: # define cache pool to use pool: 'cache.app' # define cache item id item_id: 'nelmio_api_doc_cache' ``` -------------------------------- ### Defining separate controller actions for optional parameters Source: https://symfony.com/bundles/NelmioApiDocBundle/current/faq.html The recommended solution to support optional path parameters by splitting the logic into two distinct controller actions to satisfy OpenAPI documentation requirements. ```php /** * Get all user meta data. * * @Route("/{user}/meta", * methods={"GET"}, * name="get_user_metadata" * ) * * @OA\Response( * response=200, * description="Json hashmap with all user meta data", * @OA\JsonContent(@OA\Schema( * type="object", * example={"foo": "bar", "hello": "world"} * )) * ) */ public function cgetAction(string $user) { return $this->getAction($user, null); } /** * Get user meta for a specific field. * * @Route("/{user}/meta/{metaName}", * methods={"GET"}, * name="get_user_metadata_single" * ) * * @OA\Response( * response=200, * description="A json string with the value of the requested field", * @OA\JsonContent(@OA\Schema( * type="string" * )) * ) */ public function getAction(string $user, string $metaName = null) { ... } ``` -------------------------------- ### Defining Multiple Documentation Areas Source: https://symfony.com/bundles/NelmioApiDocBundle/current/areas.html Configuration for splitting documentation into distinct areas like default, internal, commercial, and store. ```yaml nelmio_api_doc: areas: default: path_patterns: [ ^/api ] host_patterns: [ ^api\. ] internal: path_patterns: [ ^/internal ] commercial: path_patterns: [ ^/commercial ] store: # Includes routes with names containing 'store' name_patterns: [ store ] ``` -------------------------------- ### Implement PropertyDescriberInterface for Currency class Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/type_describer.html Create a class implementing PropertyDescriberInterface to define how the Currency object is described in the OpenAPI schema. ```php namespace App\PropertyDescriber; use App\ValueObject\Currency; use Nelmio\ApiDocBundle\PropertyDescriber\PropertyDescriberInterface; use OpenApi\Annotations\Schema; use Symfony\Component\PropertyInfo\Type; class CurrencyPropertyDescriber implements PropertyDescriberInterface { public function describe(array $types, Schema $property, array $context = []): void { $property->type = 'string'; $property->example = 'USD'; $property->description = 'A currency code represented as a string.'; } public function supports(array $types, array $context = []): bool { if (1 !== \count($types)) { return false; } $type = $types[0]; if (Type::BUILTIN_TYPE_OBJECT !== $type->getBuiltinType()) { return false; } return Currency::class === $type->getClassName(); } } ``` -------------------------------- ### Dump and debug configuration commands Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Use these Symfony console commands to inspect the bundle's configuration. The first displays default config values, the second shows the actual values used by your application. ```bash # displays the default config values $ php bin/console config:dump-reference nelmio_api_doc # displays the actual config values used by your application $ php bin/console debug:config nelmio_api_doc ``` -------------------------------- ### Override API URL with --server-url Source: https://symfony.com/bundles/NelmioApiDocBundle/current/commands.html Use the `--server-url` option to override the API URL when generating documentation, useful for static documentation not hosted on the API URL. ```bash $ php bin/console nelmio:apidoc:dump --format=yaml --server-url "http://example.com/api" > api.yaml ``` -------------------------------- ### Routing Configuration for Areas (PHP) Source: https://symfony.com/bundles/NelmioApiDocBundle/current/areas.html PHP routing configuration to expose different documentation areas via the {area} parameter. ```php // config/routes/nelmio_api_doc.php use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; return static function (RoutingConfigurator $routes): void { $routes->add('app.swagger_ui', '/api/doc/{area}') ->controller('nelmio_api_doc.controller.swagger_ui') ->methods(['GET']) ->defaults(['area' => 'default']); // With Redocly UI // $routes->add('app.redocly', '/api/doc/{area}') // ->controller('nelmio_api_doc.controller.redocly') // ->methods(['GET']) // ->defaults(['area' => 'default']); // With Stoplight // $routes->add('app.stoplight', '/api/doc/{area}') // ->controller('nelmio_api_doc.controller.stoplight') // ->methods(['GET']) // ->defaults(['area' => 'default']); // With Scalar // $routes->add('app.scalar', '/api/doc/{area}') // ->controller('nelmio_api_doc.controller.scalar') // ->methods(['GET']) // ->defaults(['area' => 'default']); // To expose them as JSON // $routes->add('app.swagger.areas', '/api/doc/{area}.json') // ->controller('nelmio_api_doc.controller.swagger') // ->methods(['GET']) // ->defaults(['area' => 'default']); }; ``` -------------------------------- ### Enable TypeInfo component Source: https://symfony.com/bundles/NelmioApiDocBundle/current/faq.html Enable the TypeInfo component in your configuration to improve automatic type guessing for properties. ```yaml nelmio_api_doc: type_info: true # ... ``` -------------------------------- ### Registering a Route Argument Describer in PHP Source: https://symfony.com/bundles/NelmioApiDocBundle/current/symfony_attributes.html Register the custom describer service in config/services.php using the ContainerConfigurator. ```php // config/services.php use App\Describer\CustomRouteArgumentDescriber; return function (ContainerConfigurator $container) { $container->services() ->set(CustomRouteArgumentDescriber::class) ->tag('nelmio_api_doc.route_argument_describer') ; }; ``` -------------------------------- ### Dump API documentation with nelmio:apidoc:dump Source: https://symfony.com/bundles/NelmioApiDocBundle/current/commands.html Basic usage of the `nelmio:apidoc:dump` command to generate documentation in JSON, YAML, or HTML. The `--format` option defaults to `json`. ```bash $ php bin/console nelmio:apidoc:dump [--format="..."] ``` -------------------------------- ### Configure assets_mode in nelmio_api_doc Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/ui.html Set `html_config.assets_mode` to `cdn`, `bundle`, or `offline` to control how UI assets are loaded. `cdn` loads from jsDelivr, `bundle` fetches from the vendor directory, and `offline` loads from the local `assets` directory requiring manual updates. ```yaml nelmio_api_doc: html_config: assets_mode: 'cdn' # Other values: 'bundle', 'offline' ``` -------------------------------- ### Configure model documentation with #[Context] Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Use the #[Context] attribute to override how enums or properties are documented in the API schema. ```php use Nelmio\ApiDocBundle\ModelDescriber\EnumModelDescriber; use Symfony\Component\Serializer\Attribute\Context; enum ArticleType: string { case DRAFT = 'draft'; case FINAL = 'final'; } class Article { // documented with the enum values ("draft", "final") public ArticleType $type; // documented with the enum names ("DRAFT", "FINAL"), requires a backed enum #[Context([EnumModelDescriber::FORCE_NAMES => true])] public ArticleType $typeByName; // documented using the `preview` serialization group #[Context(['groups' => ['preview']])] public Author $author; } ``` -------------------------------- ### Configure PSR-6 cache pool in nelmio_api_doc.yaml Source: https://symfony.com/bundles/NelmioApiDocBundle/current/frankenphp.html Configure a PSR-6 cache pool to ensure the documentation survives worker restarts and is shared across workers. ```yaml # config/packages/nelmio_api_doc.yaml nelmio_api_doc: cache: pool: cache.system ``` -------------------------------- ### Routing Configuration for Areas (YAML) Source: https://symfony.com/bundles/NelmioApiDocBundle/current/areas.html YAML routing configuration to expose different documentation areas via the {area} parameter. ```yaml # config/routes/nelmio_api_doc.yaml app.swagger_ui: path: /api/doc/{area} methods: GET defaults: { _controller: nelmio_api_doc.controller.swagger_ui, area: default } # With Redocly UI (use instead of Swagger UI) # app.redocly: # path: /api/doc/{area} # methods: GET # defaults: { _controller: nelmio_api_doc.controller.redocly, area: default } # With Stoplight (use instead of Swagger UI) # app.stoplight: # path: /api/doc/{area} # methods: GET # defaults: { _controller: nelmio_api_doc.controller.stoplight, area: default } # With Scalar (use instead of Swagger UI) # app.scalar: # path: /api/doc/{area} # methods: GET # defaults: { _controller: nelmio_api_doc.controller.scalar, area: default } # To expose them as JSON # app.swagger.areas: # path: /api/doc/{area}.json # methods: GET # defaults: { _controller: nelmio_api_doc.controller.swagger, area: default } ``` -------------------------------- ### Register custom model describer in services.php Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html PHP configuration to register the MoneyModelDescriber with the same tag and priority. The comment notes that autoconfigure would apply the tag automatically. ```php // config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\ModelDescriber\MoneyModelDescriber; return function(ContainerConfigurator $container) { // ... // if you're using autoconfigure, the tag will be automatically applied $services->set(App\ModelDescriber\MoneyModelDescriber::class) // register the model describer with a high priority (called earlier) ->tag('nelmio_api_doc.model_describer', [ 'priority' => 500, ]) ; }; ``` -------------------------------- ### Registering a Route Argument Describer in XML Source: https://symfony.com/bundles/NelmioApiDocBundle/current/symfony_attributes.html Register the custom describer service in config/services.xml using the nelmio_api_doc.route_argument_describer tag. ```xml ``` -------------------------------- ### Register Bundle in AppKernel Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Manually register the bundle in your AppKernel if you are not using Symfony Flex. ```php class AppKernel extends Kernel { public function registerBundles(): iterable { $bundles = [ // ... new Nelmio\ApiDocBundle\NelmioApiDocBundle(), ]; // ... } } ``` -------------------------------- ### Register Type Describer in services.php Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/type_describer.html Manual registration of the custom type describer using the PHP configuration format for Symfony services. ```php // config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\TypeDescriber\CurrencyTypeDescriber; return function (ContainerConfigurator $container) { $services = $container->services(); // if you're using autoconfigure, the tag will be automatically applied $services->set(CurrencyTypeDescriber::class) // register the type describer with a high priority (called earlier) ->tag('nelmio_api_doc.type_describer', [ 'priority' => 100, ]) ; }; ``` -------------------------------- ### Register custom model describer in services.yaml Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html Manual registration of the MoneyModelDescriber with the 'nelmio_api_doc.model_describer' tag and a priority of 500 to run earlier. This is needed when autoconfigure is disabled or priority must be set. ```yaml # config/services.yaml services: # ... App\ModelDescriber\MoneyModelDescriber: tags: # register the model describer with a high priority (called earlier) - { name: 'nelmio_api_doc.model_describer', priority: 500 } ``` -------------------------------- ### Document Controller Routes with Attributes Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Use SwaggerPHP attributes and the #[Model] attribute to document controller actions. The PHPDoc block on the method provides the summary and description. ```php namespace AppBundle\Controller; use AppBundle\Entity\Reward; use AppBundle\Entity\User; use Nelmio\ApiDocBundle\Attribute\Model; use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use Symfony\Component\Routing\Attribute\Route; class UserController { /** * List the rewards of the specified user. * * This call takes into account all confirmed awards, but not pending or refused awards. */ #[Route('/api/{user}/rewards', methods: ['GET'])] #[OA\Response( response: 200, description: 'Returns the rewards of a user', content: new OA\JsonContent( type: 'array', items: new OA\Items(ref: new Model(type: AlbumDto::class, groups: ['full'])) ) )] #[OA\Parameter( name: 'order', in: 'query', description: 'The field used to order rewards', schema: new OA\Schema(type: 'string') )] #[OA\Tag(name: 'rewards')] #[Security(name: 'Bearer')] public function fetchUserRewardsAction(User $user) { // ... } } ``` -------------------------------- ### YAML Output for Enum with Decorator Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html The resulting YAML schema for the enum including the custom x-enum-varnames extension. ```yaml components: schemas: Status: type: string enum: - active - inactive - pending x-enum-varnames: - ACTIVE - INACTIVE - PENDING ``` -------------------------------- ### Configure security schemes and global security policy Source: https://symfony.com/bundles/NelmioApiDocBundle/current/security.html Defines Bearer and ApiKeyAuth security schemes under components and applies the Bearer scheme globally to all paths. ```yaml nelmio_api_doc: documentation: components: securitySchemes: Bearer: type: http scheme: bearer ApiKeyAuth: type: apiKey in: header name: X-API-Key security: - Bearer: [] ``` -------------------------------- ### Register custom property describer in services.yaml Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/type_describer.html Manually register your custom property describer in services.yaml if you need to set a specific priority or are not using autoconfiguration. ```yaml # config/services.yaml services: # ... App\PropertyDescriber\CurrencyPropertyDescriber: tags: # register the property describer with a high priority (called earlier) - { name: 'nelmio_api_doc.property_describer', priority: 100 } ``` -------------------------------- ### Implement SelfDescribingModelInterface Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html Implement this interface in your model to define its schema documentation directly within the class using the describe method. ```php namespace App\Entity; use Nelmio\ApiDocBundle\Model\Model; use Nelmio\ApiDocBundle\ModelDescriber\SelfDescribingModelInterface; use OpenApi\Annotations\Schema; class Money implements SelfDescribingModelInterface { public static function describe(Schema $schema, Model $model): void { $schema->type = 'string'; $schema->example = '12.34 EUR'; $schema->description = 'A monetary value represented as a string.'; } } ``` -------------------------------- ### Register custom property describer in services.php Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/type_describer.html Manually register your custom property describer using the PHP configuration format for Symfony services. ```php // config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\PropertyDescriber\CurrencyPropertyDescriber; return function(ContainerConfigurator $container) { // ... // if you're using autoconfigure, the tag will be automatically applied $services->set(App\PropertyDescriber\CurrencyPropertyDescriber::class) // register the property describer with a high priority (called earlier) ->tag('nelmio_api_doc.property_describer', [ 'priority' => 100, ]) ; }; ``` -------------------------------- ### Filter Documented Routes Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Configure path and host patterns in config/packages/nelmio_api_doc.yaml to exclude unwanted routes from documentation. ```yaml # config/packages/nelmio_api_doc.yaml nelmio_api_doc: areas: path_patterns: # an array of regexps (document only routes under /api, except /api/doc) - ^/api(?!/doc$) host_patterns: # document only routes with a host of the form api.* - ^api\. ``` -------------------------------- ### Implement MyEnumDescriber Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html Custom model describer that decorates the built-in enum describer to add x-enum-varnames. ```php namespace App\ModelDescriber; use Nelmio\ApiDocBundle\Model\Model; use Nelmio\ApiDocBundle\ModelDescriber\ModelDescriberInterface; use OpenApi\Annotations\Schema; use Symfony\Component\TypeInfo\Type\EnumType; class MyEnumDescriber implements ModelDescriberInterface { public function __construct( private ModelDescriberInterface $decorates, ) { } public function describe(Model $model, Schema $schema): void { $this->decorates->describe($model, $schema); /** * @var class-string $enumClass */ $enumClass = $model->getType()->getClassName(); $xEnumVarNames = []; foreach ($enumClass::cases() as $enumCase) { $xEnumVarNames[] = $enumCase->name; } $schema->x = [ 'enum-varnames' => $xEnumVarNames, ]; } public function supports(Model $model): bool { return $this->decorates->supports($model); } } ``` -------------------------------- ### Configure Decorator in services.php Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html Register the custom model describer as a decorator for the built-in enum describer using PHP. ```php // config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\ModelDescriber\MyEnumDescriber; return function(ContainerConfigurator $container): void { // ... $services->set(MyEnumDescriber::class) ->decorate('nelmio_api_doc.model_describer.enum') // pass the old service as an argument ->args([service('.inner')]); }; ``` -------------------------------- ### Registering a Route Argument Describer in YAML Source: https://symfony.com/bundles/NelmioApiDocBundle/current/symfony_attributes.html Use the nelmio_api_doc.route_argument_describer tag to register your custom describer service in config/services.yaml. ```yaml services: App\Describer\CustomRouteArgumentDescriber: tags: - { name: nelmio_api_doc.route_argument_describer } ``` -------------------------------- ### Customize form field documentation Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Use the documentation option within a form builder to define field metadata. ```php $builder->add('username', TextType::class, [ 'documentation' => [ 'type' => 'string', // would have been automatically detected in this case 'description' => 'Your username.', ], ]); ``` -------------------------------- ### Configure operation_id_generation in PHP Source: https://symfony.com/bundles/NelmioApiDocBundle/current/configuration_reference.html Set the operation_id_generation strategy using the PHP configuration format. ```php // config/services.php use Nelmio\ApiDocBundle\Describer\OperationIdGeneration; return function (ContainerConfigurator $container) { $containerConfigurator->extension('nelmio_api_doc', [ 'operation_id_generation' => OperationIdGeneration::ALWAYS_PREPEND, ]); }; ``` -------------------------------- ### JSON Output for Enum with Decorator Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html The resulting JSON schema for the enum including the custom x-enum-varnames extension. ```json { "components": { "schemas": { "Status": { "type": "string", "enum": [ "active", "inactive", "pending" ], "x-enum-varnames": [ "ACTIVE", "INACTIVE", "PENDING" ] } } } } ``` -------------------------------- ### OpenAPI Schema attribute for model Source: https://symfony.com/bundles/NelmioApiDocBundle/current/index.html Using the OA\Schema attribute to reference a model. ```php #[OA\Schema(ref: new Model(type: App\Response\ItemResponse::class, groups: ['Default']))] ``` -------------------------------- ### JSON Output for Money Model Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html The resulting JSON schema definition for the Money model. ```json { "components": { "schemas": { "Money": { "type": "string", "example": "12.34 EUR", "description": "A monetary value represented as a string." } } } } ``` -------------------------------- ### YAML Output for Money Model Source: https://symfony.com/bundles/NelmioApiDocBundle/current/customization/model_describer.html The resulting YAML schema definition for the Money model. ```yaml components: schemas: Money: type: string example: "12.34 EUR" description: "A monetary value represented as a string." ``` -------------------------------- ### Customize property documentation with #[OA\Property] Source: https://symfony.com/bundles/NelmioApiDocBundle/current/faq.html Use the #[OA\Property] attribute or @var annotation to manually specify or customize the documentation for an object's property. ```php use Nelmio\ApiDocBundle\Attribute\Model; use OpenApi\Attributes as OA; class User { /** * @var int */ #[OA\Property(description: 'The unique identifier of the user.')] public $id; #[OA\Property(type: 'string', maxLength: 255)] public $username; #[OA\Property(ref: new Model(type: User::class))] public $friend; #[OA\Property(description: 'This is my coworker!')] public setCoworker(User $coworker) { // ... } } ``` -------------------------------- ### Configure shared schema in nelmio_api_doc.yaml Source: https://symfony.com/bundles/NelmioApiDocBundle/current/faq.html Defines a reusable schema 'NelmioImageList' in the NelmioApiDoc configuration. This schema includes a description, type, and properties such as 'total' and 'items', with 'items' referencing another schema 'ImageMetadata'. ```yaml # config/nelmio_api_doc.yaml nelmio_api_doc: documentation: components: schemas: NelmioImageList: description: "Response for some queries" type: object properties: total: type: integer example: 42 items: type: array items: $ref: "#/components/schemas/ImageMetadata" ```