rest Tutoriel
Commencer avec le repos
Recherche…
Remarques
Cette section fournit une vue d'ensemble de ce qui reste et de la raison pour laquelle un développeur peut vouloir l'utiliser.
Il devrait également mentionner tous les grands sujets dans le repos, et établir un lien avec les sujets connexes. La documentation pour le repos étant nouvelle, vous devrez peut-être créer des versions initiales de ces rubriques connexes.
REST Aperçu
REST signifie RE S tate T présentation RANSFERT et a été inventé par Roy Fielding dans sa thèse de doctorat Styles d' architecture et la conception d'architectures logicielles basées sur le réseau . Dans ce document, il identifie des principes architecturaux spécifiques tels que:
Ressources adressables: l'abstraction de clé des informations et des données dans REST est une ressource et chaque ressource doit être adressable via un URI.
Une interface uniforme et contrainte: utilisation d'un petit ensemble de méthodes bien définies pour manipuler nos ressources.
Orientation représentation: une ressource référencée par un URI peut avoir différents formats et différentes plates-formes ont besoin de formats différents. Par exemple, les navigateurs ont besoin de HTML, JavaScript nécessite des applications JSON et Java, XML, JSON, CSV, etc. en utilisant la représentation de ce service.
Communiquer sans code: les applications sans état sont plus faciles à adapter.
Hypermedia en tant que moteur de l'état d'application: laissez nos formats de données piloter les transitions d'état dans nos applications.
L'ensemble de ces principes architecturaux s'appelle REST. Les concepts de REST sont inspirés de ceux de HTTP. Roy Fielding qui nous a donné REST est également l'un des auteurs des spécifications HTTP.
Les services Web et les services Web RESTful sont des services exposés à Internet pour un accès par programme. Ce sont des api en ligne que nous pouvons appeler depuis notre code. Il existe deux types de services Web SOAP et REST «Big» pour les services Web.
Services Web RESTful : Les services Web écrits en appliquant les concepts d'architecture REST sont appelés services Web RESTful, qui se concentrent sur les ressources système et sur la manière dont l'état d'une ressource peut être transféré via le protocole HTTP à différents clients.
Ce document se concentre uniquement sur les services Web RESTful, nous n'entrerons donc pas dans les détails de SOAP WS.
Il n'y a pas de règles strictes lors de la conception de services Web RESTful tels que
- Pas de protocole standard
- Aucun canal de communication standard
- Aucune norme de définition de service
Mais SOAP a des règles strictes pour tout cela. Tous les services Web SOAP suivent les spécifications SOAP, qui déterminent ce que devraient être tous les services Web SOAP. Cette spécification est développée et gérée par un comité et si SOAP WS ne suit même pas une seule règle, par définition, ce n'est pas SOAP.
Concepts de services Web RESTful
Il y a peu de lignes directrices à prendre en compte lors de la conception et du développement de RIdful api:
- Emplacements basés sur les ressources / URI
- Utilisation correcte des méthodes HTTP
- HATEOAS (Hypermedia comme moteur de l'état d'application)
L'approche principale lors du développement des API RESTful devrait être de rendre l'API aussi «RESTful que possible».
REST sur HTTP
REST est une architecture agnostique au protocole proposée par Roy Fielding dans sa thèse (chapitre 5 étant la présentation de REST), qui généralise le concept éprouvé des navigateurs Web en tant que clients afin de découpler les clients dans un système distribué des serveurs.
Pour qu'un service ou une API soit RESTful, il doit respecter certaines contraintes telles que:
- Serveur client
- Apatride
- Cacheable
- Système en couches
- Interface uniforme
- Identification des ressources
- Représentation des ressources
- Messages auto-descriptifs
- Hypermédia
Outre les contraintes mentionnées dans la thèse de Fielding, dans son article sur le blog, les API REST doivent être basées sur un hypertexte , Fielding a précisé que le simple fait d'appeler un service via HTTP ne le rend pas RESTful . Un service doit donc également respecter d'autres règles qui sont résumées comme suit:
L'API doit respecter et ne pas violer le protocole sous-jacent. Bien que REST soit utilisé via HTTP la plupart du temps, il n'est pas limité à ce protocole.
Accent mis sur les ressources et leur présentation via des types de médias.
Les clients ne doivent pas avoir de connaissances initiales ou d'hypothèses sur les ressources disponibles ou leur état de retour ( ressource "typée" ) dans une API, mais les apprendre à la volée via des requêtes émises et des réponses analysées. Cela donne au serveur la possibilité de déplacer ou de renommer facilement les ressources sans casser l'implémentation du client.
Modèle de maturité de Richardson
Le modèle de maturité de Richardson permet d'appliquer des contraintes REST sur HTTP afin d'obtenir des services Web RESTful.
Leonard Richardson a divisé les applications en quatre couches:
- Niveau 0: utilisation de HTTP pour le transport
- Niveau 1: utilisation de l'URL pour identifier les ressources
- Niveau 2: utilisation des verbes et des statuts HTTP pour les interactions
- Niveau 3: utilisation de HATEOAS
L'accent étant mis sur la représentation de l'état d'une ressource, la prise en charge de plusieurs représentations pour la même ressource est encouragée. Une représentation pourrait donc présenter un aperçu de l'état de la ressource, tandis qu'un autre renvoie les détails complets de la même ressource.
Notez également que, compte tenu des contraintes de champ , une API n'est efficace que lorsque le 3ème niveau du RMM est implémenté .
Requêtes HTTP et réponses
Une requête HTTP est:
- Un verbe (méthode aka), la plupart du temps un de GET , POST , PUT , DELETE ou PATCH
- Une URL
- En-têtes (paires clé-valeur)
- Éventuellement un corps (charge utile, données)
Une réponse HTTP est:
- Un état, la plupart du temps 2xx (réussi) , 4xx (erreur client) ou 5xx (erreur serveur)
- En-têtes (paires clé-valeur)
- Un corps (aka charge utile, données)
Caractéristiques des verbes HTTP:
- Verbes qui ont un corps:
POST
,PUT
,PATCH
- Verbes qui doivent être sûrs (c.-à-d. Qui ne doivent pas modifier les ressources):
GET
- Verbes qui doivent être idempotents (c'est-à-dire qu'ils ne doivent plus affecter les ressources lorsqu'ils sont exécutés plusieurs fois):
GET
(nullipotent),PUT
,DELETE
body safe idempotent
GET ✗ ✔ ✔
POST ✔ ✗ ✗
PUT ✔ ✗ ✔
DELETE ✗ ✗ ✔
PATCH ✔ ✗ ✗
Par conséquent , les verbes HTTP peuvent être comparés aux fonctions CRUD :
Notez qu'une demande PUT
demande aux clients d'envoyer la ressource entière avec les valeurs mises à jour. Pour mettre à jour partiellement une ressource, vous pouvez utiliser un verbe PATCH
(voir Comment mettre à jour partiellement une ressource? ).
Statuts de réponse HTTP habituels
Succès
- 201 (CREATED) : une ressource a été créée
- 202 (ACCEPTÉ) : demande acceptée, mais processus toujours en cours
- 204 (PAS DE CONTENU) : demande satisfaite et pas de contenu supplémentaire
- Sinon: 200 (OK)
Redirection
- 304 (NON MODIFIÉ) : le client peut utiliser la version en cache de la ressource demandée
Erreurs client
- 401 (UNAUTHORIZED) : une requête anonyme accède à une API protégée
- 403 (FORBIDDEN) : une requête authentifiée n'a pas suffisamment de droits pour accéder à une API protégée
- 404 ( non trouvé ) : ressource introuvable
- 409 (CONFLICT) : état de la ressource en conflit (par exemple, un utilisateur essayant de créer un compte avec un email déjà enregistré)
- 410 (GONE) : identique à 404, mais la ressource existait
- 412 (PRECONDITION FAILED) : la requête tente de modifier une ressource dans un état inattendu
- 422 (ENTITÉ INUTILISABLE) : la charge utile de la requête est syntaxiquement valide, mais sémantiquement erronée (par exemple, un champ obligatoire qui n'a pas été évalué)
- 423 (LOCKED) : la ressource est verrouillée
- 424 (DÉFAILLANCE DÉFAILLANTE) : l'action demandée dépend d'une autre action qui a échoué
- 429 (TOO MANY REQUESTS) : l'utilisateur a envoyé trop de demandes dans un laps de temps donné
- Sinon: 400 (BAD REQUEST)
Erreurs du serveur
- 501 (NON MIS EN PLACE) : le serveur ne prend pas en charge les fonctionnalités requises pour répondre à la demande
- 503 (SERVICE UNAVAILABLE) : le serveur est actuellement incapable de traiter la demande en raison d'une surcharge temporaire ou d'une maintenance planifiée
- 507 (STOCKAGE INSUFFISANT) : le serveur ne peut pas stocker la représentation nécessaire pour terminer correctement la demande
- Sinon: 500 (ERREUR SERVEUR INTERNE)
Remarques
Rien ne vous empêche d’ajouter un corps à des réponses erronées pour rendre le rejet plus clair pour les clients. Par exemple, le 422 (UNPROCESSABLE ENTITY) est un peu vague: le corps de la réponse devrait indiquer la raison pour laquelle l'entité n'a pas pu être traitée.
HATEOAS
Chaque ressource doit fournir un hypermédia aux ressources auxquelles elle est liée. Un lien est au moins composé par:
- Un
rel
(pour rel ation, alias nom): décrit la relation entre la ressource principale et celle liée (s) - A
href
: l'URL ciblant la ou les ressources liées
Des attributs supplémentaires peuvent également être utilisés pour aider à la dépréciation, à la négociation de contenu, etc.
Cormac Mulhall explique que le client doit décider quel verbe HTTP utiliser en fonction de ce qu’il essaie de faire . En cas de doute, la documentation de l'API devrait de toute façon vous aider à comprendre les interactions disponibles avec tous les hypermédias.
Types de médias
Les types de média aident à avoir des messages auto-descriptifs. Ils jouent le rôle du contrat entre les clients et les serveurs, afin qu’ils puissent échanger des ressources et des hypermédias.
Bien que les application/json
et application/xml
soient très répandues, elles ne contiennent pas beaucoup de sémantique. Ils décrivent simplement la syntaxe globale utilisée dans le document. Des types de supports plus spécialisés prenant en charge les exigences HATEOAS doivent être utilisés (ou étendus via les types de supports du fournisseur ), tels que:
Un client indique à un serveur quels types de média il comprend en ajoutant l’en-tête Accept
à sa requête, par exemple:
Accept: application/hal+json
Si le serveur n'est pas en mesure de produire la ressource demandée dans une telle représentation, il renvoie un 406 (NOT ACCEPTABLE) . Sinon, il ajoute le type de média dans l'en Content-Type
tête Content-Type
de la réponse contenant la ressource représentée, par exemple:
Content-Type: application/hal+json
Sans état> stateful
Pourquoi?
Un serveur avec état implique que les sessions des clients sont stockées dans un stockage local d'instance de serveur (presque toujours dans les sessions de serveur Web). Cela commence à être un problème en essayant de l' échelle horizontalement : si vous cachez plusieurs instances de serveur derrière un équilibreur de charge, si un client est d' abord envoyée à l' instance n ° 1 lors de la signature, mais par la suite à l' instance n ° 2 lors de la récupération d' une ressource protégée par exemple , alors la seconde instance traitera la demande comme une requête anonyme, car la session client a été stockée localement dans l' instance n ° 1 .
Des solutions ont été trouvées pour résoudre ce problème (par exemple, en configurant la réplication de session et / ou la session sticky ), mais l’architecture REST propose une autre approche: ne faites pas de votre serveur un état, ne le mettez pas à l’état . Selon Fielding :
Chaque demande du client au serveur doit contenir toutes les informations nécessaires pour comprendre la demande et ne peut tirer parti d'aucun contexte stocké sur le serveur. L'état de la session est donc entièrement conservé sur le client.
En d'autres termes, une requête doit être traitée de la même manière, qu'elle soit envoyée à l' instance n ° 1 ou à l' instance n ° 2 . C'est pourquoi les applications sans état sont considérées comme plus faciles à adapter .
Comment?
Une approche commune est une authentification basée sur des jetons , en particulier avec les jetons Web JSON à la mode. Notez que JWT ont encore quelques problèmes mais, en particulier en ce qui concerne l' annulation et la prolongation automatique d'expiration (la remember me de fonction).
Notes de côté
Utiliser des cookies ou des en-têtes (ou autre) n'a rien à voir avec le fait que le serveur soit à l'état ou sans état: ce ne sont que des médias utilisés pour transporter des jetons (identifiant de session pour les serveurs avec état, JWT, etc.).
Lorsqu'une API RESTful est uniquement utilisée par les navigateurs, les cookies ( HttpOnly et sécurisés ) peuvent être très pratiques, car les navigateurs les attacheront automatiquement aux requêtes sortantes. Il est à noter que si vous optez pour les cookies, soyez conscient de CSRF (une bonne façon de l’empêcher est de faire en sorte que les clients génèrent et envoient la même valeur secrète unique dans un cookie et un en-tête HTTP personnalisé ).
API Cacheable avec requêtes conditionnelles
Avec l'en Last-Modified
tête Last-Modified
Le serveur peut fournir un en Last-Modified
tête de date de Last-Modified
aux réponses contenant des ressources pouvant être mises en cache. Les clients doivent ensuite stocker cette date avec la ressource.
Maintenant, chaque fois que les clients demandent à l'API de lire la ressource, ils peuvent ajouter à leurs requêtes un en If-Modified-Since
tête If-Modified-Since
contenant la dernière date de Last-Modified
reçue et stockée. Le serveur doit ensuite comparer l'en-tête de la demande et la date de dernière modification réelle de la ressource. S'ils sont égaux, le serveur renvoie un 304 (NON MODIFIÉ) avec un corps vide: le client demandeur doit utiliser la ressource actuellement en cache.
De plus, lorsque les clients demandent à l'API de mettre à jour la ressource (avec un verbe non sécurisé), ils peuvent ajouter un en If-Unmodified-Since
tête If-Unmodified-Since
. Cela permet de gérer les conditions de course: si l'en-tête et la date de dernière modification sont différentes, le serveur renvoie un 412 (PRECONDITION FAILED) . Le client doit alors lire le nouvel état de la ressource avant de tenter de modifier la ressource.
Avec l'en ETag
tête ETag
Un ETag (balise d'entité) est un identifiant pour un état spécifique d'une ressource. Il peut s'agir d'un hachage MD5 de la ressource pour une validation forte ou d'un identifiant spécifique à un domaine pour une validation faible .
Fondamentalement, le processus est le même qu'avec l'en Last-Modified
tête Last-Modified
: le serveur fournit un en ETag
tête ETag
aux réponses contenant des ressources pouvant être mises en cache, et les clients doivent ensuite stocker cet identifiant avec la ressource.
Les clients fournissent ensuite un en If-None-Match
tête If-None-Match
lorsqu'ils veulent lire la ressource, contenant le dernier ETag qu'ils ont reçu et stocké. Le serveur peut maintenant retourner un 304 (NON MODIFIÉ) si l'en-tête correspond à l'ETag réel de la ressource.
Encore une fois, les clients peuvent fournir un en If-Match
tête If-Match
lorsqu'ils souhaitent modifier la ressource, et le serveur doit renvoyer un 412 (PRECONDITION FAILED) si l'ETag fourni ne correspond pas à celui actuel.
Notes complémentaires
ETag> date
Si les clients fournissent à la fois la date et ETag dans leurs demandes, la date doit être ignorée. De la RFC 7232 ( ici et ici ):
Un destinataire DOIT ignorer
If-Modified-Since
/If-Unmodified-Since
si la requête contient un champ d'enIf-Match
têteIf-None-Match
/If-Match
; la condition dansIf-None-Match
/If-Match
est considérée comme un remplacement plus précis de la condition dansIf-Modified-Since
/If-Unmodified-Since
, et les deux ne sont combinés que pour interagir avec les anciens intermédiaires qui pourrait ne pas implémenterIf-None-Match
/If-Match
.
Peu profonds
En outre, bien qu'il soit évident que les dernières dates modifiées sont conservées avec les ressources côté serveur, plusieurs approches sont disponibles avec ETag.
Une approche habituelle consiste à implémenter des ETags peu profonds: le serveur traite la requête comme si aucun en-tête conditionnel n'avait été donné, mais à la toute fin seulement, il génère l'ETag de la réponse qu'il est sur le point de retourner (par exemple en le hachant). avec celui fourni. Ceci est relativement facile à mettre en œuvre car seul un intercepteur HTTP est nécessaire (et de nombreuses implémentations existent déjà en fonction du serveur). Cela étant dit, il convient de mentionner que cette approche permettra d’ économiser la bande passante, mais pas les performances du serveur :
Une implémentation plus profonde du mécanisme ETag pourrait potentiellement offrir des avantages beaucoup plus importants - par exemple, servir certaines requêtes du cache sans avoir à effectuer le calcul - mais l'implémentation ne serait certainement pas aussi simple, ni aussi pluggable que l'approche superficielle décrit ici.
Pièges communs
Pourquoi ne devrais-je pas mettre des verbes dans une URL?
HTTP n'est pas RPC : ce qui fait que HTTP est très différent de RPC, c'est que les requêtes sont dirigées vers des ressources . Après tout, URL signifie Uniform Resource Locator, et une URL est un URI : Uniform Resource Idenfitier. L'URL cible la ressource à traiter , la méthode HTTP indique ce que vous voulez en faire . Les méthodes HTTP sont également appelées verbes : les verbes dans les URL n'ont alors aucun sens. Notez que les relations HATEOAS ne doivent pas contenir de verbes, car les liens ciblent également les ressources.
Comment mettre à jour partiellement une ressource?
Comme les requêtes PUT
demandent aux clients d'envoyer la ressource entière avec les valeurs mises à jour, PUT /users/123
ne peut pas être utilisé pour mettre à jour simplement le courrier électronique d'un utilisateur par exemple. Comme l'explique William Durand dans Please. Ne corrige pas comme un idiot. , plusieurs solutions compatibles REST sont disponibles:
- Exposez les propriétés de la ressource et utilisez la méthode
PUT
pour envoyer une valeur mise à jour, car la spécificationPUT
indique que des mises à jour de contenu partielles sont possibles en ciblant une ressource identifiée séparément avec un état recouvrant une partie de la ressource plus grande :
PUT https://example.com/api/v1.2/users/123/email
body:
new.email@example.com
- Utilisez une requête
PATCH
contenant un ensemble d'instructions décrivant la manière dont la ressource doit être modifiée (par exemple, après le correctif JSON ):
PATCH https://example.com/api/v1.2/users/123
body:
[
{ "op": "replace", "path": "/email", "value": "new.email@example.com" }
]
- Utilisez une requête
PATCH
contenant une représentation partielle de la ressource, comme proposé dans le commentaire de Matt Chapman :
PATCH https://example.com/api/v1.2/users/123
body:
{
"email": "new.email@example.com"
}
Qu'en est-il des actions qui ne correspondent pas au monde des opérations CRUD?
Citant Vinay Sahni dans les meilleures pratiques pour concevoir une API RESTful pragmatique :
C'est là que les choses peuvent devenir floues. Il existe plusieurs approches:
Restructurer l'action pour qu'elle apparaisse comme un champ de ressource. Cela fonctionne si l'action ne prend pas de paramètres. Par exemple, une action enable pourrait être mappée sur un champ booléen
activated
et mis à jour via un PATCH dans la ressource.Traitez-le comme une sous-ressource avec les principes RESTful. Par exemple, l’API de GitHub vous permet de créer une liste avec
PUT /gists/:id/star
et unstar avecDELETE /gists/:id/star
.Parfois, vous n'avez vraiment aucun moyen de faire correspondre l'action à une structure RESTful judicieuse. Par exemple, une recherche multi-ressources n'a pas vraiment de sens pour être appliquée au point de terminaison d'une ressource spécifique. Dans ce cas,
/search
aurait le plus de sens même s'il ne s'agit pas d'une ressource. Ceci est OK - il suffit de faire ce qui est juste du point de vue du consommateur d'API et de s'assurer qu'il est clairement documenté pour éviter toute confusion.
Pratiques communes
L'API est documentée. Des outils sont disponibles pour vous aider à créer votre documentation, par exemple Swagger ou Spring REST Docs .
L'API est versionnée , via les en-têtes ou via l'URL:
https://example.com/api/v1.2/blogs/123/articles
^^^^
- Les ressources ont des noms au pluriel :
https://example.com/api/v1.2/blogs/123/articles
^^^^^ ^^^^^^^^
- Les URL utilisent kebab-case (les mots sont en minuscules et séparés par des tirets):
https://example.com/api/v1.2/quotation-requests
^^^^^^^^^^^^^^^^^^
- HATEOAS fournit un lien "auto" vers les ressources, en se ciblant elles-mêmes:
{
...,
_links: {
...,
self: { href: "https://example.com/api/v1.2/blogs/123/articles/789" }
^^^^
}
}
- Les relations HATEOAS utilisent lowerCamelCase (les mots sont en minuscules, puis en majuscule, sauf le premier, et les espaces sont omis), pour permettre aux clients JavaScript d'utiliser la notation par points tout en respectant les conventions de nommage JavaScript lors de l'accès aux liens:
{
...,
_links: {
...,
firstPage: { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=1&pageSize=25" }
^^^^^^^^^
}
}
Gestion des blogs via une API HTTP RESTful
Les exemples suivants utilisent HAL pour exprimer HATEOAS et utilisent:
- CURIE (URI compact): utilisé pour fournir des liens vers la documentation de l'API
- Modèles d'URI : URI qui inclut les paramètres qui doivent être remplacés avant la résolution de l'URI
Obtenez le blog 123
Demande
GET https://example.com/api/v1.2/blogs/123
headers:
Accept: application/hal+json
Réponse
status: 200 (OK)
headers:
Content-Type: application/hal+json
body:
{
"id": 123,
"title": "The blog title",
"description": "The blog description",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123" },
"doc:articles": { "href": "https://example.com/api/v1.2/blogs/123/articles{?pageIndex,pageSize}", "templated": true }
}
}
Créer un nouvel article dans le blog 123
Demande
POST https://example.com/api/v1.2/blogs/123/articles
headers:
Content-Type: application/json
Accept: application/hal+json
X-Access-Token: XYZ
body:
{
"title": "The title 2",
"content": "The content 2"
}
Réponse
status: 201 (CREATED)
headers:
Content-Type: application/hal+json
body:
{
"id": 789,
"title": "The title 2",
"content": "The content 2",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
}
}
Obtenir l'article 789 du blog 123
Demande
GET https://example.com/api/v1.2/blogs/123/articles/789
headers:
Accept: application/hal+json
Réponse
status: 200 (OK)
headers:
Content-Type: application/hal+json
body:
{
"id": 789,
"title": "The title 2",
"content": "The content 2",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
}
}
Obtenez la 4ème page de 25 articles du blog 123
Demande
GET https://example.com/api/v1.2/blogs/123/articles?pageIndex=4&pageSize=25
headers:
Accept: application/hal+json
Réponse
status: 200 (OK)
headers:
Content-Type: application/hal+json
body:
{
"pageIndex": 4,
"pageSize": 25,
"totalPages": 26,
"totalArticles": 648,
"_link": {
"firstPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=1&pageSize=25" },
"previousPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=3&pageSize=25" },
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=4&pageSize=25" },
"nextPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=5&pageSize=25" },
"lastPage": { "href": "https://example.com/api/v1.2/blogs/123/articles?pageIndex=26&pageSize=25" }
},
"_embedded": [
{
...
}, {
"id": 456,
"title": "The title 1",
"content": "The content 1",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/456" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/456/comments{?pageIndex,pageSize}", "templated": true }
}
}, {
"id": 789,
"title": "The title 2",
"content": "The content 2",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
}
}, {
...
}
]
}
Mettre à jour l'article 789 du blog 123
Demande
PUT https://example.com/api/v1.2/blogs/123/articles/789
headers:
Content-Type: application/json
Accept: application/hal+json
X-Access-Token: XYZ
body:
{
"id": 789,
"title": "The title 2 updated",
"content": "The content 2 updated"
}
Réponse
status: 200 (OK)
headers:
Content-Type: application/hal+json
body:
{
"id": 789,
"title": "The title 2 updated",
"content": "The content 2 updated",
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"self": { "href": "https://example.com/api/v1.2/blogs/123/articles/789" },
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" },
"doc:comments": { "href": "https://example.com/api/v1.2/blogs/123/articles/789/comments{?pageIndex,pageSize}", "templated": true }
}
}
Remarques
- L'identifiant utilisé pour identifier la ressource à mettre à jour est celui de l'URL : celui du corps (le cas échéant) doit être ignoré en silence.
- Comme une demande
PUT
met à jour la ressource entière, si aucuncontent
n'a été envoyé, il doit avoir été supprimé de la ressource persistante.
Supprimer l'article 789 du blog 123
Demande
DELETE https://example.com/api/v1.2/blogs/123/articles/789
headers:
Accept: application/hal+json
X-Access-Token: XYZ
Réponse
status: 204 (NO CONTENT)
headers:
Content-Type: application/hal+json
body:
{
"_links": {
"curies": [{ "name": "doc", "href": "https://example.com/docs/{rel}", "templated": true }],
"doc:blog": { "href": "https://example.com/api/v1.2/blogs/123", "title": "The blog title" }
}
}
Violant le repos
<stock>
<add>
<item>
<name>Milk</name>
<quantity>2</quantity>
</item>
</add>
</stock>
Mettre ce corps sur une ressource comme /stocks/123
viole l’idée derrière REST. Pendant que ce corps est put
et qu'il contient toutes les informations nécessaires, il est accompagné d'un appel de méthode pour add
quelque part lorsque le corps est traité. Après le REST, on afficherait l' item
dans /stocks/123/items/
.