Retour au Blog

Swagger nelmio bundle et ses fonctionnalités, pourquoi l’utilise t-on ?

Swagger nelmio bundle et ses fonctionnalités, pourquoi l’utilise t-on ?

SWAGGER :

Swagger Aka OpenApi, désigne l’ensemble des outils qui aident les développeurs dans la conception, le build, la documentation et la consommation d’API, qui sont au format JSON ou YAML selon leur utilisation, et qui fonctionnent avec HTML et JavaScript.

Alors, quels sont ces outils ? et comment faire une documentation réussie avec Nelmio ApiDoc Bundle ?

Pour implémenter et visualiser les API, vous aurez besoin de :

  • Swagger Editor : est composé d’un éditeur qui permet de définir ses Api, et d’un visualisateur qui donne une vue interactive de ce qui a été saisi dans l’éditeur

swagger editor

  • Swagger Codegen : génère une librairie d’Api en fournissant une spécification OpenApi ;
  • Swagger UI: est l’outil de documentation qui permet de visualiser et d’interagir avec les Api dans l’interface graphique. Ainsi, il permet de tester les Api et de les rendre accessibles aux clients. l'image ci-dessous représente la liste des API ;
Liste des API
Liste des API
Interaction avec l’API
Interaction avec l’API

Avantages Swagger :

  • Le code permet une génération automatique de la documentation
  • Évolution parallèle du système et de la documentation, et enregistrement automatique des modifications
  • Qualité et gain de temps

Gain de temps et donc de qualité. Le développeur n’a plus besoin de s’attarder sur la documentation, il a donc plus de temps à consacrer au développement de ses API.

Nelmio ApiDoc Bundle

Le bundle NelmioApiDocBundle vous permet de générer de la documentation au format OpenAPI (Swagger) et fournit un bac à sable pour expérimenter de manière interactive avec l'API, vous n’avez plus besoin de rédiger la documentation de manière manuelle. En plus de ça, cette dernière va évoluer en parallèle avec le code.

Nous allons donc vous exposer les étapes de mise en place de Nelmio Bundle pour automatiser la génération de la documentation symfony

1ère étape : Installation

- Ouvrir une console de commande

- Entrer le répertoire de votre projet

- Exécuter la commande suivante pour télécharger la dernière version de ce bundle :

$ composer require nelmio/api-doc-bundle

Par défaut, seules les routes sous /api sont documentées. Il faut mettre à jour l'expression régulière à nelmio_api_doc.areas.path_patterns dans config/packages/nelmio_api_doc.yaml pour modifier cette politique.

Si vous n'utilisez pas Flex, ajoutez le bundle à votre noyau :

class AppKernel extends Kernel

{

   public function registerBundles(): iterable

   {

       $bundles = [

           // ...

           new Nelmio\ApiDocBundle\NelmioApiDocBundle(),

       ];

       // ...

   }

}

Pour parcourir votre documentation avec Swagger UI, enregistrez la route suivante :

# config/routes.yaml

app.swagger_ui:

   path: /api/doc

   methods: GET

   defaults: { _controller: nelmio_api_doc.controller.swagger_ui }

Si vous souhaitez également l'exposer en JSON, enregistrez cette route :

# config/routes.yaml

app.swagger:

   path: /api/doc.json

   methods: GET

   defaults: { _controller: nelmio_api_doc.controller.swagger }

En fin d'installation, vous allez trouvez des itinéraires dont vous ne voulez peut être pas dans votre documentation, tels que /_profiler/.

Alors, pour résoudre ce problème, vous pouvez filtrer les routes documentées en configurant le bundle :

# 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\.

Le bundle génère une documentation OpenAPI à partir de votre application Symfony grâce aux Describers . L'un extrait les données des annotations SwaggerPHP, l'autre de vos routes, etc.

2ème étape : Configuration des informations globales

Vous pouvez configurer les informations globales dans la documentation .infosection de configuration du bundle.

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

       components:

           securitySchemes:

               Bearer:

                   type: http

                   scheme: bearer

                   bearerFormat: JWT

       security:

           - Bearer: []

PS : En cas d'utilisation de Flex, cette configuration est présente par défaut sous config/packages/nelmio_api_doc.yaml. Il faut l'adapter à votre application.

3ème étape : Documentation

Pour documenter vos routes, utilisez les annotations SwaggerPHP et la Nelmio\ApiDocBundle\Annotation\Model annotation dans vos contrôleurs :

namespace AppBundle\Controller;

use AppBundle\Entity\Reward;

use AppBundle\Entity\User;

use Nelmio\ApiDocBundle\Annotation\Model;

use Nelmio\ApiDocBundle\Annotation\Security;

use OpenApi\Annotations as OA;

use Symfony\Component\Routing\Annotation\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 an user",

    *     @OA\JsonContent(

    *        type="array",

    *        @OA\Items(ref=@Model(type=Reward::class, groups={"full"}))

    *     )

    * )

    * @OA\Parameter(

    *     name="order",

    *     in="query",

    *     description="The field used to order rewards",

    *     @OA\Schema(type="string")

    * )

    * @OA\Tag(name="rewards")

    * @Security(name="Bearer")

    */

   public function fetchUserRewardsAction(User $user)

   {

       // ...

   }

}

Lorsque vous utilisez ce bundle, vous n'avez pas besoin de spécifier de chemins car vous pouvez facilement documenter les modèles; ainsi que d'autres propriétés décrites ci-dessous, parce qu'elles peuvent être automatiquement documentées à l'aide de l'intégration Symfony.

4ème étape : Utilisation des modèles

Un modèle peut être un type de formulaire Symfony, une entité Doctrine ORM ou un objet PHP général.

Cette annotation a deux options :

  • type pour spécifier le type de votre modèle :

/**

* @OA\Response(

*     response=200,

*     @Model(type=User::class)

* )

*/

  • groups pour spécifier les groupes de sérialisation utilisés pour (dé)sérialiser votre modèle :

/**

* @OA\Response(

*     response=200,

*     @Model(type=User::class, groups={"non_sensitive_data"})

* )

*/

  • groups peut également être utilisé pour spécifier les groupes de validation de contraintes utilisés pour (dé)sérialiser votre modèle, mais cela doit être activé dans la configuration :

nelmio_api_doc:

   use_validation_groups: true

   # ...

Lorsque cette option est activée, les groupes définis dans le modèle s'appliqueront à la fois aux propriétés du sérialiseur et aux contraintes du validateur. Prenez la classe de modèle ci-dessous :

use Symfony\Component\Serializer\Annotation\Groups;

use Symfony\Component\Validator\Constraints as Assert;

class UserDto

{

   /**

    * @Groups({"default", "create", "update"})

    * @Assert\NotBlank(groups={"default", "create"})

    */

   public string $username;

}

La contrainte NotBlank ne s'appliquera qu'au groupe default et create , mais pas à update. En termes plus pratiques : la propriété `username` s'afficherait required à la fois pour la création et la valeur par défaut du modèle, mais pas pour la mise à jour. Lorsque vous utilisez des générateurs de code pour créer des clients API, cela se traduit souvent par une validation et des types côté client. NotBlank ajoute required empêchera ce type de propriété d'être nullable, par exemple.

use OpenApi\Annotations as OA;

/**

 * shows `username` as `required` in the OpenAPI schema (not nullable)

 * @OA\Response(

 *     response=200,

 *     @Model(type=UserDto::class, groups={"default"})

 * )

 */

/**

 * Similarly, this will make the username `required` in the create

 * schema

 * @OA\RequestBody(@Model(type=UserDto::class, groups={"create"}))

 */

/**

 * But for updates, the `username` property will not be required

 * @OA\RequestBody(@Model(type=UserDto::class, groups={"update"}))

 */

Lorsqu'il est utilisé à la racine de @OA\Response et @OA\Parameter, @Modelest automatiquement imbriqué dans un @OA\Schema.

Le type de média par défaut est application/json.

Pour utiliser @Model directement dans un @OA\Schema, @OA\Itemsou @OA\Property, vous devez utiliser le champ $ref :

/**

* @OA\Response(

*     @OA\JsonContent(ref=@Model(type=User::class))

* )

*

* or

*

* @OA\Response(@OA\XmlContent(

*     @OA\Schema(type="object",

*         @OA\Property(property="foo", ref=@Model(type=FooClass::class))

*     )

* ))

*/

Types de formulaire Symfony :

Vous pouvez personnaliser la documentation d'un champ de formulaire en utilisant l'otion documentation :

$builder->add('username', TextType::class, [

   'documentation' => [

       'type' => 'string', // would have been automatically detected in this case

       'description' => 'Your username.',

   ],

]);

Si vous souhaitez personnaliser la documentation de la propriété d'un objet, vous pouvez utiliser @OA\Property:

use Nelmio\ApiDocBundle\Annotation\Model;

use OpenApi\Annotations 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=@Model(type=User::class))

    */

   public $friend;

   /**

    * @OA\Property(description="This is my coworker!")

    */

   public setCoworker(User $coworker) {

       // ...

   }

}