Slim 4 - API documentation with Swagger

Daniel Opitz
Daniel Opitz
12 Jun 2020

Table of contents



This article explains how to expose swagger-ui inside your Slim project through a route (eg. /docs), without the need for node.

Just add a reference to your swagger Yaml or JSON specification, and enjoy swagger-ui in all it’s glory.




To parse the OpenAPI Yaml file, we have to install a good Yaml parser:

composer require symfony/yaml

For demonstration purpose download this example file, or just use your own specification:

Save the yaml file in the resources/docs/ directory. If not exists, create it.


Create a new template file: templates/docs/swagger.twig and copy/paste this content:

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <title>API Specification - Swagger UI</title>
    <link rel="stylesheet" type="text/css"
<div id="swagger-ui"></div>
<script src=""></script>
<script src=""></script>
    window.onload = function () {
        const ui = SwaggerUIBundle({
            spec: {{ spec|raw }},
            dom_id: '#swagger-ui',
            deepLinking: true,
            presets: [
            plugins: [
        window.ui = ui


Create a new action class: src/Action/Docs/SwaggerUiAction.php


namespace App\Action\Docs;

use App\Responder\Responder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\Yaml\Yaml;

final class SwaggerUiAction
     * @var Responder
    private $responder;

     * The constructor.
     * @param Responder $responder The responder
    public function __construct(Responder $responder)
        $this->responder = $responder;

     * Action.
     * @param ServerRequestInterface $request The request
     * @param ResponseInterface $response The response
     * @return ResponseInterface The response
    public function __invoke(
        ServerRequestInterface $request, 
        ResponseInterface $response
    ): ResponseInterface {
        // Path to the yaml file
        $yamlFile = __DIR__ . '/../../../resources/docs/petstore.yaml';

        $viewData = [
            'spec' =>json_encode(Yaml::parseFile($yamlFile)),

        return $this->responder->render($response, 'docs/swagger.twig', $viewData);

Add a new route:

$app->get('/docs/v1', \App\Action\Docs\SwaggerUiAction::class);

Then navigate to http://localhost/docs/v1 and you should see a pretty Swagger UI documentation.