Api Platform conference
Register now
v2.1 Swagger / Open API Support
API Platform Conference
September 18-19, 2025 | Lille & online

The international conference on the API Platform Framework

Get ready for our special anniversary edition!

Lear more about the event, register for the conference, and get ready for two days of inspiration, ideas, and knowledge-sharing with our incredible lineup of renowned specialists and advocates.

This edition is shaping up to be our biggest yet — secure your seat now at the best price before we sell out!

Only a few tickets left!

API Platform natively support the Open API (formerly Swagger) API documentation format. It also integrates a customized version of Swagger UI, a nice tool to display the API documentation in a user friendly way.

Screenshot

# Overriding the Swagger Documentation

Symfony allows to decorate services, here we need to decorate api_platform.swagger.normalizer.documentation.

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

# app/config/services.yml
services:
    'AppBundle\Swagger\SwaggerDecorator':
        decorates: 'api_platform.swagger.normalizer.documentation'
        arguments: [ '@AppBundle\Swagger\SwaggerDecorator.inner' ]
        autoconfigure: false
<?php
// src/AppBundle/Swagger/SwaggerDecorator.php

namespace AppBundle\Swagger;

use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class SwaggerDecorator implements NormalizerInterface
{
    private $decorated;

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

    public function normalize($object, $format = null, array $context = [])
    {
        $docs = $this->decorated->normalize($object, $format, $context);

        $customDefinition = [
            'name' => 'fields',
            'definition' => 'Fields to remove of the outpout',
            'default' => 'id',
            'in' => 'query',
        ];


	// e.g. add a custom parameter
	$docs['paths']['/foos']['get']['parameters'][] = $customDefinition;

	// Override title
	$docs['info']['title'] = 'My Api Foo';

        return $docs;
    }

    public function supportsNormalization($data, $format = null)
    {
        return $this->decorated->supportsNormalization($data, $format);
    }
}

# Using the Swagger Context

Sometimes you may want to have additional information included in your Swagger documentation. The following configuration will provide additional context to your Swagger definitions:

<?php
// src/AppBundle/Entity/Product.php

namespace AppBundle\Entity;

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

/**
 * @ApiResource
 * @ORM\Entity
 */
class Product // The class name will be used to name exposed resources
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @param string $name A name property - this description will be avaliable in the API documentation too.
     *
     * @ORM\Column
     * @Assert\NotBlank
     *
     * @ApiProperty(
     *     attributes={
     *         "swagger_context"={
     *             "type"="string",
     *             "enum"={"one", "two"},
     *             "example"="one"          
     *         }
     *     }
     * )
     */
    public $name;

    /**
     * @ORM\Column
     * @Assert\DateTime
     *
     * @ApiProperty(
     *     attributes={
     *         "swagger_context"={"type"="string", "format"="date-time"}
     *     }
     * )
     */
    public $timestamp;
}

Or in YAML:

# src/AppBundle/Resources/config/api_resources/resources.yml
resources:
    AppBundle\Entity\Product:
      properties:
        name:
          attributes:
            swagger_context:
              type: string
              enum: ['one', 'two']
              example: one
        timestamp:
          attributes:
            swagger_context:
              type: string
              format: date-time

Will produce the following Swagger documentation:

{
  "swagger": "2.0",
  "basePath": "/",

  "definitions": {
    "Product": {
      "type": "object",
      "description": "This is a product.",
      "properties": {
        "id": {
          "type": "integer",
          "readOnly": true
        },
        "name": {
          "type": "string",
          "description": "This is a name.",
          "enum": ["one", "two"],
          "example": "one"
        },
        "timestamp": {
          "type": "string",
          "format": "date-time"
        }
      }
    }
  }
}

# Changing the Swagger UI Location

Sometimes you may want to have the API at one location, and the Swagger UI at a different location. This can be done by disabling the Swagger UI from the API Platform configuration file and manually adding the Swagger UI controller.

# Disabling Swagger UI

# app/config/config.yml

api_platform:
    # ...
    enable_swagger_ui: false

# Manually Registering the Swagger UI Controller

# app/config/routing.yml
swagger_ui:
    path: /docs
    controller: api_platform.swagger.action.ui

Change /docs to your desired URI you wish Swagger to be accessible on.

# Enable Swagger doc for API Gateway

AWS API Gateway supports Swagger 2.0 partially, but it requires some changes. Fortunately, API Platform provides a way to be compatible with both Swagger 2.0 & API Gateway.

To enable API Gateway compatibility on your Swagger doc, add api_gateway=true query parameter:

http://www.example.com/docs.json?api_gateway=true

You can also help us improve the documentation of this page.

Made with love by

Les-Tilleuls.coop can help you design and develop your APIs and web projects, and train your teams in API Platform, Symfony, Next.js, Kubernetes and a wide range of other technologies.

Learn more

Copyright © 2023 Kévin Dunglas

Sponsored by Les-Tilleuls.coop