Une API, aussi bien pensée soit-elle, n’est rien sans une bonne documentation. Une option pourrait être de documenter votre API à la main. C’est tout à fait faisable, et suffisant dans de nombreux cas.
Ceci étant, la documentation étant un problème qui se pose pratiquement pour toutes les API, vous vous en doutez, un bundle existe précisément pour répondre à cette demande : Nelmio.
L’idée de ce bundle va être de générer un site web (oui oui, un site web !) qui va reprendre l’intégralité de nos routes pour les documenter, mais qui va même nous fournir un outil pour tester ces routes directement !
Installez Nelmio
La première étape consiste, comme toujours, à installer ce bundle :
composer require nelmio/api-doc-bundle
Pensez à accepter la recette proposée pour que les fichiers de configuration soient automatiquement créés.
Une fois Nelmio installé, le fichier nelmio_api_doc.yaml
devrait avoir été créé dans le dossier routes de la configuration.
# config\routes\nelmio_api_doc.yaml
# Expose your documentation as JSON swagger compliant
app.swagger:
path: /api/doc.json
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger }
## Requires the Asset component and the Twig bundle
## $ composer require twig asset
app.swagger_ui:
path: /api/doc
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }
Nous allons juste décommenter les dernières lignes pour activer la route /api/doc
.
Notez le commentaire juste au-dessus qui nous précise que pour fonctionner, cette route a besoin d’installer Twig, le moteur de template.
Installons-le :
composer require twig asset
À ce stade, la documentation existe déjà sur la route /api/doc
, il nous faut juste rendre cette route accessible. En effet, dans le fichier security.yaml
, nous avons dit qu’il fallait un token pour toutes les routes, sauf celle qui permet d’obtenir le token.
Nous allons donc ajouter une seconde exception pour la route ^/api/doc
, qui doit avoir un accès public :
# config\packages\security.yaml
(...)
access_control:
- { path: ^/api/login, roles: PUBLIC_ACCESS }
- { path: ^/api/doc, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
(...)
Et… c’est fini, vous avez déjà une documentation !
Celle-ci sera accessible normalement à l’URL :https://127.0.0.1:8000/api/doc
.
Nous y voyons les diverses routes disponibles, et quelle méthode HTTP doit être utilisée.
Configurez JWT et Nelmio
Nelmio nous propose non seulement une documentation, mais ce site est également un outil pour tester nos routes comme nous le faisions avec Postman.
En cliquant, par exemple, sur Author pour avoir la liste des auteurs, on accède à une interface qui permet d’exécuter la requête. Mais si on le fait, on se heurte à un petit souci : Erreur 401 : Pas de token JWT.
C’est parfaitement logique, nous n’avons pas récupéré de token. Plus encore, l’authentification étant gérée par Symfony et LexikJWTAuthenticator, nous n’avons même pas la route ici présente.
Nous allons donc expliquer à Nelmio qu’une route existe, et qu’il faut la présenter. Dans le dossier config/packages
se trouve un fichier nelmio_api_doc.yaml
qui sert précisément à cela :
# config\packages\nelmio_api_doc.yaml
nelmio_api_doc:
documentation:
info:
title: Books
description: Une API d'OpenClassrooms avec des livres, des autrices et des auteurs !
version: 2.0.0
paths:
/api/login_check:
post:
operationId: postCredentialsItem
tags:
- Token
summary: Permet d'obtenir le token JWT pour se logger.
requestBody:
description: Crée un nouveau token JWT
content:
application/json:
schema:
$ref: '#/components/schemas/Credentials'
responses:
'200':
description: Récupère le token JWT
content:
application/json:
schema:
$ref: '#/components/schemas/Token'
components:
schemas:
Token:
type: object
properties:
token:
type: string
readOnly: true
Credentials:
type: object
properties:
username:
type: string
default: admin@bookapi.com
password:
type: string
default: password
securitySchemes:
bearerAuth:
type: apiKey
in: header
name: Authorization # or another header name
security:
- bearerAuth: []
areas: # to filter documented areas
path_patterns:
- ^/api(?!/doc$) # Accepts routes under /api except /api/doc
Ce fichier précise de nombreuses choses, en particulier des informations sur l’application et la route login_check
elle-même. Si vous voulez en savoir plus, comme toujours la documentation officielle sur la sécurité (en anglais) est faite pour vous !
En bref, nous pouvons voir dans ce fichier :
info
: cette section contient des informations générales sur notre application ;path
: précise la route pour réaliser la récupération de notre token et des informations de documentation (summary, requestBody, responses…) ;components
: décrit ce qui a été appelé dans la partie path, en particulier :token
: dit que l’on veut un token, chaîne de caractères,credential
: précise les informations de connection (en particulier username et password),securitySchemes
: explique que nous voulons un champ Authorization dans le header de la requête.
Et c’est tout ! Nous pouvons maintenant tester. La première chose va être de récupérer le token, mais une nouvelle route vient d'apparaître : /api/login_check
.
Et avec l’exécution, nous obtenons notre code :
Il faut maintenant spécifier ce code en cliquant sur le champ Authorize, qui est apparu tout en haut du formulaire, sans oublier, comme avec Postman, de faire précéder ce code de Bearer
:
Et voilà, nous sommes désormais identifiés, et nous pouvons tester nos routes !
Améliorez les informations sur les ressources dans la documentation
Nous avons accès à nos routes, mais les commentaires sont un peu légers, les réponses possibles restent inconnues, et les paramètres difficiles à comprendre.
Là encore, Nelmio a tout prévu, et avec quelques annotations directement dans les contrôleurs, il est possible de tout paramétrer, ou presque !
Prenons par exemple la route qui retourne l’ensemble des livres. Pour l’instant, aucune information sur la pagination n’est fournie.
Améliorons cela dans le fichier BookController.php
. D’abord, nous renseignons les use
qui seront utiles pour les annotations.
<?php
// src\Controller\BookController.php
// ...
use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Security;
use OpenApi\Annotations as OA;
Et ensuite, nous pouvons annoter chaque méthode, ici getAllBooks
.
<?php
// src\Controller\BookController.php
// ...
/**
* Cette méthode permet de récupérer l'ensemble des livres.
*
* @OA\Response(
* response=200,
* description="Retourne la liste des livres",
* @OA\JsonContent(
* type="array",
* @OA\Items(ref=@Model(type=Book ::class, groups={"getBooks"}))
* )
* )
* @OA\Parameter(
* name="page",
* in="query",
* description="La page que l'on veut récupérer",
* @OA\Schema(type="int")
* )
*
* @OA\Parameter(
* name="limit",
* in="query",
* description="Le nombre d'éléments que l'on veut récupérer",
* @OA\Schema(type="int")
* )
* @OA\Tag(name="Books")
*
* @param BookRepository $bookRepository
* @param SerializerInterface $serializer
* @param Request $request
* @return JsonResponse
*/
#[Route('/api/books', name: 'books', methods: ['GET'])]
public function getAllBooks(BookRepository $bookRepository, SerializerInterface $serializer, Request $request, TagAwareCacheInterface $cache): JsonResponse
{
// ...
Ici sont définis les réponses (en l'occurrence, la réponse 200
) et les paramètres disponibles (en l'occurrence, limit
et page
).
Regardons rapidement les éléments présents :
@OA\Response
: définit les réponses possibles (ici un code de retour200
) :@OA\JsonContent
: explique le type du contenu retourné (ici un tableau d’entité(@model) Book
).
@OA\Parameter
: définit les paramètres acceptés par la méthode :@OA\Schema
: le type du paramètre, ici, tout simplement un chiffre.
@OA\Tag
: le groupe de la méthode, ce qui permet de classer les méthodes pour l’affichage par la suite.
Nous aurions également pu ajouter la réponse 401 Unauthorized
, qui est une des réponses possibles. Cela aurait été possible en ajoutant une autre annotation @OA\Response
, comme nous l’avons fait pour le stat.
Regardons maintenant le résultat :
Nos deux nouveaux paramètres sont désormais présents. Notez également que la route a été rangée dans Books
grâce au tag qui a été précisé en commentaire.
En résumé
La documentation est un point essentiel dans la qualité globale d’une API, et permet un meilleur taux d’adoption de l’API.
Nelmio est un outil qui permet de générer un site web qui documente, et même permet de tester notre application.
Nelmio est configurable, et permet en particulier de se connecter à JWT.
Félicitations à nouveau, avec cette documentation votre API est désormais complète.
Le chapitre suivant va nous permettre d’être à la fois dans la peau de l’API ET dans celle d’un client qui interroge une API.