Les API REST devraient-elles implémenter les liens hypermédia HATEOAS ?
En bref
HATEOAS (Hypermedia as the Engine of Application State) est théoriquement élégant mais pratiquement complexe. La plupart des API omettent le HATEOAS complet et utilisent des liens hypermédia sélectifs pour la pagination, les ressources associées et les actions. Modern PetstoreAPI implémente des liens hypermédia pratiques sans obliger les clients à être entièrement pilotés par l'hypermedia.
Introduction
Vous lisez des articles sur la conception d'API REST. Vous rencontrez HATEOAS (Hypermedia as the Engine of Application State). L'explication dit : « Les clients devraient découvrir toutes les actions via des liens hypermédia, et non pas coder en dur des URL. »
Vous pensez : « Cela semble compliqué. Quelqu'un fait-il réellement cela ? »
La réponse : pas vraiment. HATEOAS est la contrainte REST la plus souvent ignorée. Roy Fielding (qui a inventé REST) dit qu'elle est essentielle. La plupart des concepteurs d'API la jugent peu pratique. Résultat : la plupart des API « REST » ne sont pas véritablement RESTful selon la définition de Fielding.
Modern PetstoreAPI adopte une approche pragmatique : utiliser les liens hypermédia là où ils apportent de la valeur (pagination, ressources associées, actions) mais sans obliger les clients à être entièrement pilotés par l'hypermedia.
Dans ce guide, vous apprendrez ce qu'est HATEOAS, pourquoi il est controversé et comment implémenter des liens hypermédia pratiques en utilisant Modern PetstoreAPI comme référence.
Qu'est-ce que HATEOAS ?
HATEOAS est une contrainte REST qui stipule que les clients devraient découvrir les capacités d'une API via des liens hypermédia, et non via la documentation.
Le concept
Au lieu de coder en dur des URL :
// Le client code en dur les URL
const response = await fetch('https://petstoreapi.com/v1/pets/123');
const pet = await response.json();
// Le client connaît la structure de l'URL
await fetch(`https://petstoreapi.com/v1/pets/${pet.id}/orders`);
Les clients suivent les liens à partir des réponses :
// Le client commence à la racine
const root = await fetch('https://petstoreapi.com/v1');
const rootData = await root.json();
// Le client suit le lien vers les animaux de compagnie
const petsUrl = rootData._links.pets.href;
const pets = await fetch(petsUrl);
const petsData = await pets.json();
// Le client suit le lien vers un animal de compagnie spécifique
const petUrl = petsData._links.self.href;
const pet = await fetch(petUrl);
const petData = await pet.json();
// Le client suit le lien vers les commandes
const ordersUrl = petData._links.orders.href;
const orders = await fetch(ordersUrl);
La théorie
Avec HATEOAS :
1. Les clients ne codent pas en dur les URL
Les URL peuvent changer sans casser les clients. Le serveur contrôle la structure des URL.
2. Les clients découvrent les capacités
Si un lien existe, l'action est disponible. Sinon, elle n'est pas disponible (ou n'est pas autorisée pour cet utilisateur).
3. Les API s'auto-documentent
Les clients explorent l'API en suivant les liens, comme on navigue sur un site web.
Exemple : Réponse HATEOAS complète
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"name": "Fluffy",
"species": "CAT",
"status": "AVAILABLE",
"_links": {
"self": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24"
},
"update": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24",
"method": "PUT"
},
"delete": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24",
"method": "DELETE"
},
"orders": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/orders"
},
"adopt": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/adopt",
"method": "POST"
}
}
}
Le client n'a pas besoin de connaître les schémas d'URL. Il suit les liens.
Le débat sur HATEOAS
HATEOAS est controversé car la théorie et la pratique divergent.
Arguments en faveur de HATEOAS
1. Couplage faible
Les clients ne dépendent pas de la structure des URL. Le serveur peut modifier les URL sans casser les clients.
2. Découvrabilité
Les clients peuvent explorer l'API sans lire la documentation.
3. Actions pilotées par l'état
Les liens indiquent les actions disponibles. Si un animal est adopté, le lien « adopter » disparaît.
4. Vrai REST
Roy Fielding affirme que HATEOAS est essentiel à REST. Sans cela, vous ne faites pas de REST.
Arguments contre HATEOAS
1. Complexité
Les clients ont besoin d'une logique d'analyse hypermédia. Les clients HTTP simples deviennent des machines à états complexes.
2. Performance
Les clients effectuent plusieurs requêtes pour découvrir les URL. L'accès direct aux URL est plus rapide.
3. Difficulté de débogage
Suivre les liens rend le débogage plus difficile. Vous ne pouvez pas simplement exécuter un curl sur une URL, vous devez suivre la chaîne de liens.
4. Outils insuffisants
La plupart des clients HTTP, des outils de test et des générateurs de documentation supposent des URL codées en dur.
5. Personne ne le fait
GitHub, Stripe, Twilio, Twitter – les principales API n'utilisent pas le HATEOAS complet. S'ils n'en ont pas besoin, en avez-vous besoin ?
La réalité
La plupart des API se disent « REST » mais ignorent HATEOAS. Ce sont en fait des « API HTTP » ou des « API de type REST ». Le véritable REST (avec HATEOAS) est rare.
Liens hypermédia pratiques
Au lieu d'un HATEOAS complet, utilisez des liens hypermédia là où ils apportent de la valeur.
1. Liens de pagination
Problème : Les clients doivent construire des URL de pagination.
Solution : Fournir des liens suivant/précédent.
{
"data": [...],
"pagination": {
"page": 2,
"limit": 20,
"totalPages": 10
},
"links": {
"self": "https://petstoreapi.com/v1/pets?page=2&limit=20",
"first": "https://petstoreapi.com/v1/pets?page=1&limit=20",
"prev": "https://petstoreapi.com/v1/pets?page=1&limit=20",
"next": "https://petstoreapi.com/v1/pets?page=3&limit=20",
"last": "https://petstoreapi.com/v1/pets?page=10&limit=20"
}
}
Avantage : Les clients ne construisent pas les URL de pagination. Ils suivent les liens.
2. Liens vers des ressources associées
Problème : Les clients doivent connaître les schémas d'URL pour les ressources associées.
Solution : Fournir des liens vers les ressources associées.
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"name": "Fluffy",
"_links": {
"self": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24",
"orders": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/orders",
"owner": "https://petstoreapi.com/v1/users/019b4127-54d5-76d9-b626-0d4c7bfce5b6"
}
}
Avantage : Les clients découvrent les ressources associées sans documentation.
3. Liens d'action
Problème : Les clients doivent savoir quelles actions sont disponibles.
Solution : Fournir des liens pour les actions disponibles.
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"status": "AVAILABLE",
"_links": {
"adopt": {
"href": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/adopt",
"method": "POST"
}
}
}
Si l'animal est déjà adopté :
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"status": "ADOPTED",
"_links": {
// Pas de lien "adopt" - action non disponible
}
}
Avantage : Les liens indiquent les actions disponibles en fonction de l'état.
4. Pagination basée sur un curseur
Problème : Les clients doivent construire des URL de curseur.
Solution : Fournir des URL suivant/précédent opaques.
{
"data": [...],
"links": {
"next": "https://petstoreapi.com/v1/pets?cursor=eyJpZCI6IjAxOWI0MTMyIn0"
}
}
Avantage : Les clients n'analysent pas les curseurs. Ils suivent les liens.
Comment Modern PetstoreAPI utilise l'hypermedia
Modern PetstoreAPI utilise des liens hypermédia sélectifs.
Liens de pagination
Tous les points d'accès aux collections incluent des liens de pagination :
GET /v1/pets?limit=20
{
"data": [...],
"pagination": {
"limit": 20,
"hasMore": true
},
"links": {
"self": "https://petstoreapi.com/v1/pets?limit=20",
"next": "https://petstoreapi.com/v1/pets?cursor=eyJpZCI6IjAxOWI0MTMyIn0&limit=20"
}
}
Liens vers des ressources associées
Les réponses des ressources incluent des liens vers des ressources associées :
GET /v1/pets/019b4132-70aa-764f-b315-e2803d882a24
{
"id": "019b4132-70aa-764f-b315-e2803d882a24",
"name": "Fluffy",
"ownerId": "019b4127-54d5-76d9-b626-0d4c7bfce5b6",
"_links": {
"self": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24",
"owner": "https://petstoreapi.com/v1/users/019b4127-54d5-76d9-b626-0d4c7bfce5b6",
"orders": "https://petstoreapi.com/v1/pets/019b4132-70aa-764f-b315-e2803d882a24/orders"
}
}
Pas de HATEOAS complet
Modern PetstoreAPI n'exige pas que les clients soient pilotés par l'hypermedia. Les clients peuvent :
Option 1 : Suivre les liens (piloté par l'hypermedia)
const pet = await fetch(petUrl);
const ownerUrl = pet._links.owner.href;
const owner = await fetch(ownerUrl);
Option 2 : Construire les URL (traditionnel)
const pet = await fetch(`https://petstoreapi.com/v1/pets/${petId}`);
const owner = await fetch(`https://petstoreapi.com/v1/users/${pet.ownerId}`);
Les deux approches fonctionnent. Les liens sont fournis pour des raisons de commodité, et non d'obligation.
Tester les API hypermédia avec Apidog
Apidog vous aide à tester les liens hypermédia et à valider leur exactitude.
Tester la présence des liens
Vérifier que les réponses incluent les liens attendus :
// Script de test Apidog
pm.test("Response includes pagination links", () => {
const links = pm.response.json().links;
pm.expect(links).to.have.property('self');
pm.expect(links).to.have.property('next');
});
Tester la validité des liens
Suivre les liens et vérifier qu'ils fonctionnent :
// Script de test Apidog
const nextUrl = pm.response.json().links.next;
pm.sendRequest(nextUrl, (err, response) => {
pm.test("Next link returns 200", () => {
pm.expect(response.code).to.equal(200);
});
});
Tester le format des liens
Vérifier que les liens suivent le format attendu :
pm.test("Links are absolute URLs", () => {
const links = pm.response.json().links;
Object.values(links).forEach(link => {
pm.expect(link).to.match(/^https:\/\//);
});
});
Quand utiliser HATEOAS
Utilisez les liens hypermédia lorsqu'ils apportent de la valeur. Ignorez-les lorsqu'ils n'en apportent pas.
Utiliser les liens hypermédia pour :
1. Pagination – Les clients ne devraient pas construire les URL de pagination
2. Ressources associées – Navigation pratique
3. Actions dépendantes de l'état – Afficher les actions disponibles en fonction de l'état de la ressource
4. Flux de travail complexes – Guider les clients à travers des processus multi-étapes
Ignorer HATEOAS pour :
1. API CRUD simples – Les clients peuvent construire les URL facilement
2. API internes – Les équipes peuvent coordonner les changements d'URL
3. API critiques en termes de performance – Les liens supplémentaires augmentent la taille de la réponse
4. API mobiles – La bande passante est importante, les liens ajoutent une surcharge
Conclusion
HATEOAS est théoriquement élégant mais pratiquement complexe. La plupart des API omettent le HATEOAS complet et utilisent des liens hypermédia sélectifs là où ils apportent de la valeur.
Modern PetstoreAPI démontre l'hypermedia pratique : liens de pagination, liens vers des ressources associées et liens d'action – sans obliger les clients à être entièrement pilotés par l'hypermedia.
Utilisez Apidog pour tester les liens hypermédia, valider leur exactitude et vous assurer que votre API offre une navigation utile.
Points clés à retenir :
- Le HATEOAS complet est rare et complexe
- Les liens hypermédia sélectifs ajoutent de la valeur sans complexité
- Les liens de pagination sont la fonctionnalité hypermédia la plus utile
- N'obligez pas les clients à être pilotés par l'hypermedia
- Testez les liens pour vous assurer qu'ils fonctionnent correctement
Explorez la documentation de Modern PetstoreAPI pour voir une implémentation hypermédia pratique.
FAQ
HATEOAS est-il obligatoire pour les API REST ?
Selon Roy Fielding (inventeur de REST), oui. En pratique, non. La plupart des API « REST » ignorent HATEOAS et sont techniquement des « API HTTP » ou des « API de type REST ».
Que signifie HATEOAS ?
Hypermedia as the Engine of Application State. Cela signifie que les clients découvrent les capacités d'une API via des liens hypermédia, et non des URL codées en dur.
Les principales API utilisent-elles HATEOAS ?
Non. GitHub, Stripe, Twilio et la plupart des grandes API n'utilisent pas le HATEOAS complet. Elles peuvent inclure certains liens hypermédia (pagination, ressources associées) mais n'exigent pas que les clients soient pilotés par l'hypermedia.
Quelle est la différence entre HATEOAS et les liens hypermédia ?
HATEOAS est une contrainte exigeant que les clients soient entièrement pilotés par l'hypermedia. Les liens hypermédia sont simplement des liens dans les réponses. Vous pouvez inclure des liens sans imposer HATEOAS.
Devrais-je implémenter HATEOAS dans mon API ?
Probablement pas le HATEOAS complet. Utilisez des liens hypermédia sélectifs pour la pagination et les ressources associées. N'obligez pas les clients à être pilotés par l'hypermedia, sauf si vous avez une raison spécifique.
Comment tester les API HATEOAS ?
Utilisez Apidog pour vérifier la présence des liens, suivre les liens et valider leur exactitude. Testez que les liens renvoient les réponses attendues.
Qu'est-ce que le format HAL ?
HAL (Hypertext Application Language) est un format standard pour les liens hypermédia. Il utilise les champs _links et _embedded. Modern PetstoreAPI utilise un format de lien inspiré de HAL.
Les clients peuvent-ils ignorer les liens hypermédia ?
Oui. Si votre API fournit des liens mais n'exige pas que les clients les utilisent, les clients peuvent construire les URL directement. C'est l'approche pragmatique que la plupart des API adoptent.
