Skip to main content
Illustration isométrique d'une architecture API REST polyglotte moderne. Un ordinateur portable sur la gauche envoie des paquets de données à une API Gateway centrale (logo Java). La Gateway est connectée à quatre services backend : un service Python (logo serpent), un service Go (logo gopher), une base de données PostgreSQL (logo éléphant), et un autre service de base de données générique. L'arrière-plan est un dégradé bleu foncé avec des motifs de circuits imprimés.

Construire et Tester des APIs REST : De la Théorie au Code Prêt pour la Production

9 min 1,901 words

Dans cet article, je vais couvrir les fondamentaux des APIs REST. Je partagerai un repository contenant un exemple basique d’une stack microservices (consommant et exposant des APIs REST) complet avec des tests d’intégration. Enfin, je partagerai un ensemble de bonnes pratiques et de principes pour les développeurs travaillant en équipe.

Ce post est basé sur un cours que j’ai donné à Ada Tech School, une école de code inclusive en France, alors que je travaillais comme Engineering Manager chez Swan. Vous pouvez trouver les slides utilisés pour ce cours à la fin de l’article.

Définitions

Quel que soit le programme que vous écrivez, il a presque toujours besoin de communiquer avec son environnement :

  • Arguments d’entrée (Input arguments) : Passage de valeurs via l’Interface en Ligne de Commande (CLI), clés de configuration ou chemins de fichiers.

  • Entrée Utilisateur (User Input) : Invites nécessitant une interaction utilisateur (un classique des entretiens techniques : ex. “entrer un nombre, retourner tous les nombres premiers inférieurs à X”).

  • Notifications : Envoi d’emails à la fin de l’exécution ou lors de la détection d’erreurs.

  • Données Externes : SMS, notifications push, lecture de fichiers ou requêtes en base de données.

Dans le contexte du web, le besoin pour des programmes distincts de communiquer entre eux a fortement augmenté, menant à la standardisation des interfaces.

API

API signifie Application Programming Interface (Interface de Programmation d’Application). Cela désigne l’interface qui permet à différents services de communiquer, partager des données et déclencher des fonctionnalités.

Bien que le terme soit générique, je me concentrerai spécifiquement sur les APIs utilisant HTTP (HyperText Transfer Protocol). HTTP est le protocole de couche application standard pour la communication web, introduit par Tim Berners-Lee au CERN en 1989. Lorsque vous consultez cette page, votre navigateur demande son contenu à un serveur via HTTP.

Note : Il existe de nombreuses APIs non-HTTP actives, telles que les WebSockets (pour des canaux de communication persistants), MQTT (utilisé par Home Assistant ou Facebook Messenger), et AMQP (utilisé par des Message Brokers comme RabbitMQ).

Les Acteurs Majeurs des APIs HTTP

Bien qu’il en existe beaucoup, quatre technologies représentent la grande majorité des APIs HTTP utilisées dans l’industrie aujourd’hui :

  • SOAP : Un protocole construit sur XML.

  • gRPC : Un framework d’Appel de Procédure à Distance (RPC) haute performance utilisant Protobuf.

  • GraphQL : Un langage de requête permettant aux clients de demander exactement les données dont ils ont besoin depuis plusieurs sources en une seule requête.

  • REST : Voir ci-dessous 😁.

REST

REST (REpresentational State Transfer) a été introduit par Roy Fielding en 2000 dans sa thèse de doctorat comme “une solution pour créer des applications basées sur un réseau mondial”.

Pour être considérée comme RESTful, une API doit respecter les contraintes suivantes :

  • Modèle Client-Serveur : Les responsabilités sont strictement séparées. Le client et le serveur communiquent via une interface, leur permettant d’évoluer indépendamment (couplage faible).

  • Stateless (Sans état) : Le serveur ne conserve aucun état de session entre les requêtes. Tout contexte nécessaire (comme les tokens d’authentification) doit être envoyé par le client avec chaque requête.

  • Mise en cache (Cacheability) : Les réponses doivent se définir comme pouvant être mises en cache ou non, empêchant les clients de réutiliser des données obsolètes ou inappropriées.

  • Interface Uniforme : Cela simplifie et découple l’architecture via quatre sous-contraintes :

    • Identification des Ressources : Les ressources sont identifiées dans les requêtes à l’aide d’URIs. La ressource elle-même et sa représentation (JSON, XML) sont distinctes.

    • Manipulation des Ressources via Représentations : Un client détenant une représentation d’une ressource a suffisamment d’informations pour la modifier ou la supprimer.

    • Messages Auto-Descriptifs : Chaque message inclut suffisamment d’informations (comme Content-Type) pour décrire comment traiter le message.

    • Hypermedia as the Engine of Application State (HATEOAS) : Le serveur doit fournir des hyperliens vers d’autres actions et ressources disponibles, permettant au client de naviguer dans l’API dynamiquement, un peu comme un humain navigue sur un site web.

  • Système en Couches (Layered System) : Le client ne peut pas dire s’il est connecté directement au serveur final ou à un intermédiaire (comme un load balancer ou un cache).

  • Code à la Demande (Optionnel) : Les serveurs peuvent temporairement étendre la fonctionnalité du client en transférant du code exécutable (ex. scripts).

Une note sur la Réalité vs la Théorie

La plupart des APIs “REST” dans l’industrie prennent des libertés avec ces règles, particulièrement HATEOAS. Comme Roy Fielding l’a noté (source) :

[…] if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API […]

Je m’excuse auprès de Roy Fielding, mais c’est une liberté que je prends personnellement lors de la construction d’APIs, et une que je prendrai dans cet article. Si vous voulez plonger plus profondément dans la conformité REST stricte, jetez un œil à :

Note terminologique : REST est le style architectural. Une API l’implémentant est une API RESTful. En pratique, les termes sont souvent utilisés de manière interchangeable.

Tendances et Popularité

Rassembler des données d’utilisation est difficile, regardons donc les tendances de recherche Google pour jauger l’intérêt au fil du temps.

SOAP

SOAP (initialement XML-RPC, 1996) est le vétéran. L’intérêt de recherche est resté relativement stable mais bas au cours des 20 dernières années.

Intérêt au fil du temps pour l'API SOAPIntérêt au fil du temps pour l’API SOAP

gRPC

gRPC (sorti en 2016) montre une augmentation continue de l’intérêt, atteignant un pic récemment.

Intérêt au fil du temps pour gRPCIntérêt au fil du temps pour gRPC

GraphQL

GraphQL (Facebook, 2012) suit une tendance similaire à gRPC, bien qu’avec une légère baisse depuis 2022.

Intérêt au fil du temps pour GraphQLIntérêt au fil du temps pour GraphQL

REST API

Plus récent que SOAP mais plus ancien que les autres (2000), REST a connu une augmentation massive et continue de popularité, ne reflétant le léger plafonnement de GraphQL que depuis 2022.

Intérêt au fil du temps pour l'API RESTIntérêt au fil du temps pour l’API REST

Anatomie d’une API REST

Une API REST est typiquement composée d’une collection d’endpoints. Chaque endpoint est défini par un verbe HTTP, une URL, un payload de données optionnel, et des headers (en-têtes).

URL

L’URL (Uniform Resource Locator) spécifie l’adresse d’une ressource sur internet. Exemple :

https://www.bigseeder.com/trees/tree1/apples?color=red&tasty=true
  • Protocole : https (HTTP sécurisé).

  • Domaine : www.bigseeder.com.

  • Chemin (Path) : /trees/tree1/apples. C’est hiérarchique. Nous accédons à la collection trees, sélectionnons un arbre spécifique (tree1), puis accédons à sa ressource apples.

  • Paramètres de requête (Query Parameters) : ?color=red&tasty=true. Tout ce qui suit le ? filtre ou modifie la requête (détaillé ci-dessous).

Verbes HTTP

Le verbe HTTP indique à l’API quelle action effectuer sur la ressource.

Les “Big 5” Verbes Courants :

  • GET : Récupérer des ressources. Sûr et idempotent.

  • POST : Créer une ressource. Les données sont envoyées dans le corps (body).

  • PUT : Mettre à jour une ressource complètement. Remplace l’entité ressource entière.

  • PATCH : Mettre à jour une ressource partiellement. Modifie uniquement des champs spécifiques.

  • DELETE : Supprimer une ressource.

Verbes Moins Courants :

  • HEAD : Comme GET, mais retourne uniquement les headers (pas de corps). Utile pour vérifier si une ressource existe.

  • OPTIONS : Retourne les méthodes autorisées/requises pour une ressource spécifique (CORS).

  • TRACE : Test de bouclage pour le débogage.

  • CONNECT : Établit un tunnel (ex. pour SSL).

Astuce : Consultez les docs web MDN pour approfondir.

Headers (En-têtes)

Les Headers sont des métadonnées. Ils ne contiennent pas la ressource elle-même mais décrivent le contexte : format (Content-Type), authentification (Authorization), règles de cache, ou infos client.

Transmission de Données

La façon dont vous envoyez des données dépend du verbe et de l’intention.

1. Paramètres de Requête (Query Parameters)

Utilisés avec GET pour le filtrage, le tri ou la pagination. Exemple : Obtenir 10 chats Chartreux.

curl "https://api.thecatapi.com/v1/images/search?breed_ids=char&limit=10"

2. Paramètres de Chemin (Path Parameters)

Utilisés pour identifier une ressource spécifique dans le chemin de l’URL. Exemple : Obtenir l’image avec l’ID 3NC7vIjMR.

https://api.thedogapi.com/v1/images/3NC7vIjMR

3. Corps de Requête (Request Body - JSON)

Utilisé avec POST, PUT, PATCH. Exemple : Créer une tâche dans Todoist.

Bash

curl "https://api.todoist.com/rest/v2/tasks" \
    -X POST \
    --data '{"content": "Acheter du lait", "project_id": "2203306141"}' \
    -H "Content-Type: application/json"

4. Paramètres de Formulaire & Multipart

Utilisés pour soumettre des données de formulaire ou uploader des fichiers. Exemple : Uploader un fichier sur Slack.

curl -X POST "https://slack.com/api/files.upload" \
    -F "file=@picture.png" \
    -H "Authorization: Bearer <votre_token>"

Codes de Statut

Chaque réponse d’API est accompagnée d’un entier à 3 chiffres indiquant le résultat.

  • 2xx (Succès) : 200 OK, 201 Created.

  • 4xx (Erreur Client) : 400 Bad Request, 401 Unauthorized (authentification manquante), 403 Forbidden (authentification/droits invalides), 404 Not Found.

  • 5xx (Erreur Serveur) : 500 Internal Server Error, 502 Bad Gateway.

Un Exemple Concret : Le Repo Polyglotte “FarmHub”

Pour démontrer ces concepts, j’ai construit un projet multi-services, multi-langages appelé FarmHub. Jetez un œil au repository ici.

Il imite une architecture microservices où différentes équipes pourraient utiliser différentes stacks :

  1. Species Service (NodeJS/Express) : Gère les espèces animales.

  2. Animals Service (PHP/Slim) : Gère les animaux, les liant aux espèces et aux fermiers.

  3. Pictures Service (Go/Mux) : Gère les assets d’images.

  4. Farmers Service (Python/FastAPI) : Gère les profils des fermiers.

  5. Farm Service (Java/Spring Boot) : Le service “Gateway” ou Agrégateur. Il consomme les 4 autres APIs pour exposer un point d’entrée unifié.

Pourquoi c’est important : Ce repo inclut une Collection Postman et des Tests d’Intégration (utilisant Newman). Il montre comment tester un système distribué efficacement.

Principes pour Concevoir de Bonnes APIs

Basé sur mon expérience en tant que Lead Dev et Engineering Manager, voici les règles d’or pour votre équipe :

1. La Spécification d’Abord

Ne sous-estimez jamais la phase de spécification. Définissez vos URLs, verbes, payloads, et surtout vos cas d’erreur. Scénario : Si votre endpoint “Get Farm” appelle le service “Picture” et que ce service est en panne, que se passe-t-il ? Est-ce que toute la requête échoue (500) ? Ou retournez-vous des données partielles avec un champ image null (200) ? Ces décisions doivent être prises avant de coder.

2. Suivez les Standards (Ne soyez pas “Original”)

Utilisez les verbes HTTP et les codes de statut standards. Anti-Pattern :

// Retourner un code HTTP 200 OK avec ce corps :
{
 "error": "Server Exploded",
 "code": 500
}

Cela casse les outils de monitoring et embrouille les clients. Si c’est une erreur serveur, retournez un code de statut 500. Si l’utilisateur a envoyé de mauvaises données, retournez 400. Cela permet aux clients de savoir s’ils doivent réessayer (5xx) ou corriger leur requête (4xx).

3. Gardez les Stacks Cohérentes (Si possible)

Bien que mon exemple de repo soit “polyglotte” à des fins éducatives, dans une vraie startup, évitez de mélanger 5 langages différents. Cela augmente la charge cognitive et la friction d’intégration.

4. Principe de Responsabilité Unique (Single Responsibility Principle)

Un endpoint doit faire une seule chose. Ne faites pas en sorte qu’un endpoint GET /users déclenche aussi un processus de facturation ou une écriture massive d’analytics. Les effets de bord rendent les APIs imprévisibles et difficiles à tester.

5. Ne Retournez Que Ce Qui Est Nécessaire

Évitez de rendre vos payloads “future-proof” en ajoutant des données “au cas où”. Cela gonfle le trafic réseau et la charge de la base de données. Si vous avez besoin d’analytics, utilisez un outil/endpoint d’analytics dédié, ne vous greffez pas sur votre API opérationnelle.

Conclusion

Les APIs REST sont la colonne vertébrale du web moderne. Comprendre l’anatomie d’une requête (Verbe, URL, Header, Body) et les contraintes de l’architecture est crucial pour tout développeur.

Allez voir le Repository FarmHub pour voir le code en action, lancer les tests, et explorer comment 5 langages différents peuvent parler la même langue HTTP.

Liens Utiles