← API REST : concevoir, mûrir, documenter

Documenter son API avec OpenAPI

≈ 25 minutes · Prérequis : Authentification et sécurité : API keys, JWT, OAuth2

Le gain du jour : écrire une véritable spécification OpenAPI — un contrat lisible par des humains et par des machines — plutôt qu’une documentation en prose qui se désynchronise inévitablement du code.

Le problème que résout OpenAPI

Une documentation d’API écrite « à la main » (page wiki, README) se désynchronise du code dès le premier changement oublié. OpenAPI (anciennement Swagger Specification, aujourd’hui maintenue par l’OpenAPI Initiative) propose un format standard, en YAML ou JSON, pour décrire une API REST de façon structurée et exploitable par des outils : rendu visuel automatique, génération de code client, tests de contrat, mocks — tout ce qu’on verra dans la prochaine leçon avec Swagger.

OpenAPI ≠ Swagger

OpenAPI est le nom de la spécification (le format du document). Swagger est le nom historique de l’ensemble d’outils créés par SmartBear autour de ce format (Swagger UI, Swagger Editor, Swagger Codegen) — on y revient en leçon 10. Le format s’appelle « OpenAPI » depuis la version 3.0 (2017) ; « Swagger » reste utilisé par habitude pour désigner le format 2.0 et les outils.

Anatomie d’un document OpenAPI

Un document OpenAPI est un seul fichier YAML (ou JSON), organisé en grandes sections :

openapi: 3.1.0
info:
  title: API Bibliothèque
  version: "1.0.0"
  description: Gère les livres d'une médiathèque.
servers:
  - url: https://api.exemple.com/v1
paths:
  /books:
    get:
      summary: Liste les livres
      # ... voir plus bas
components:
  schemas:
    # ... les structures de données réutilisables

Décrire un endpoint : paths

Reprenons GET /books/{id} : lire un livre par son identifiant.

paths:
  /books/{id}:
    get:
      summary: Récupère un livre par son identifiant
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Le livre trouvé
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Book"
        "404":
          description: Livre introuvable

Chaque élément se lit directement comme une phrase : pour GET /books/{id}, il faut un paramètre id dans le chemin, de type entier ; en cas de succès (200), la réponse est un Book ; sinon, 404.

Décrire les données : components.schemas

Plutôt que de répéter la structure d’un Book à chaque endpoint qui le manipule, on la définit une fois dans components.schemas et on la référence avec $ref :

components:
  schemas:
    Book:
      type: object
      required: [id, title, author]
      properties:
        id:
          type: integer
          example: 42
        title:
          type: string
          example: "Fondation"
        author:
          type: string
          example: "Isaac Asimov"
        published_year:
          type: integer
          nullable: true

required liste les champs obligatoires ; les autres (published_year ici) sont optionnels. example alimente automatiquement les exemples affichés dans Swagger UI — sujet de la prochaine leçon.

Décrire un POST avec corps de requête

paths:
  /books:
    post:
      summary: Crée un nouveau livre
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BookInput"
      responses:
        "201":
          description: Livre créé
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Book"
        "422":
          description: Données invalides

Remarque l’usage d’un schéma différent en entrée (BookInput, sans id — le serveur le génère) et en sortie (Book, avec id) : une pratique courante et saine, qui évite qu’un client puisse imposer son propre identifiant à la création.

Décrire l’authentification

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
security:
  - bearerAuth: []

Ce bloc déclare que l’API attend un en-tête Authorization: Bearer <jwt> (leçon 8) sur toutes les routes par défaut — un outil comme Swagger UI affichera alors un bouton « Authorize » pour saisir le jeton une fois, et l’appliquera à tous les essais d’endpoints.

Vérifie ta compréhension

1. Quelle est la différence entre OpenAPI et Swagger ?

2. À quoi sert la section components.schemas d'un document OpenAPI ?

3. Pourquoi utiliser un schéma BookInput distinct de Book pour un POST /books ?

À toi de jouer

  1. Écris le document OpenAPI complet (openapi, info, paths, components.schemas) pour une ressource Task (une tâche à faire) avec deux endpoints : GET /tasks (liste) et POST /tasks (création). Chaque Task a un id, un title et un done booléen.

  2. Ajoute à ton document une route DELETE /tasks/{id} avec une réponse 204 No Content en cas de succès, et 404 si la tâche n’existe pas.

Pour aller plus loin

📖 Source principale : OpenAPI Specification v3.1 — documentation officielle, la référence complète et à jour du format, maintenue par l’OpenAPI Initiative (Linux Foundation).

🗂 Fiche de référence associée : Verbes, codes, en-têtes — antisèche.