Je conçois un service Web RESTful utilisant WebApi et je me demandais quelles réponses HTTP et quels corps de réponse renvoyer lors de la mise à jour / de la création d'objets.
Par exemple, je peux utiliser la méthode POST pour envoyer du JSON au service Web, puis créer un objet. Est-il recommandé de définir ensuite le statut HTTP sur créé (201) ou ok (200) et de simplement renvoyer un message tel que "Nouvel employé ajouté" ou de renvoyer l'objet envoyé à l'origine?
Il en va de même pour la méthode PUT. Quel est le meilleur statut HTTP à utiliser et dois-je renvoyer l'objet créé ou juste un message? Considérant le fait que l'utilisateur sait quel objet il tente de créer / mettre à jour de toute façon.
Des pensées?
Exemple:
Ajouter un nouvel employé:
POST /api/employee HTTP/1.1
Host: localhost:8000
Content-Type: application/json
{
"Employee": {
"Name" : "Joe Bloggs",
"Department" : "Finance"
}
}
Mettre à jour un employé existant:
PUT /api/employee HTTP/1.1
Host: localhost:8000
Content-Type: application/json
{
"Employee": {
"Id" : 1
"Name" : "Joe Bloggs",
"Department" : "IT"
}
}
Réponses:
Réponse avec objet créé / mis à jour
HTTP/1.1 201 Created
Content-Length: 39
Content-Type: application/json; charset=utf-8
Date: Mon, 28 Mar 2016 14:32:39 GMT
{
"Employee": {
"Id" : 1
"Name" : "Joe Bloggs",
"Department" : "IT"
}
}
Réponse avec juste un message:
HTTP/1.1 200 OK
Content-Length: 39
Content-Type: application/json; charset=utf-8
Date: Mon, 28 Mar 2016 14:32:39 GMT
{
"Message": "Employee updated"
}
Réponse avec juste le code de statut:
HTTP/1.1 204 No Content
Content-Length: 39
Date: Mon, 28 Mar 2016 14:32:39 GMT
UPDATE/INSERT ... RETURNING
variante Postgresql pour SQL. C'est extrêmement pratique, en particulier parce qu'il conserve la soumission de nouvelles données et demande la version mise à jour atomique.Réponses:
Comme avec la plupart des choses, cela dépend. Votre compromis est la facilité d'utilisation par rapport à la taille du réseau. Il peut être très utile pour les clients de voir la ressource créée. Il peut inclure des champs renseignés par le serveur, tels que last-creation-time. Comme vous semblez inclure le
id
au lieu de l’utiliserhateoas
, les clients voudront probablement voir l’identifiant de la ressource qu’ils viennent d’POST
éditer.Si vous n'incluez pas la ressource créée, veuillez ne pas créer de message arbitraire. Les champs 2xx et Emplacement fournissent suffisamment d'informations pour que les clients puissent être sûrs que leur demande a été traitée correctement.
la source
Personnellement, je reviens toujours uniquement
200 OK
.Pour citer votre question
Pourquoi ajouter de la bande passante supplémentaire (qui pourrait être payante) pour dire au client ce qu'il sait déjà?
la source
200
/204 No Content
pour éviter de confondre jQuery et autres.@ iswinky Je renvoie toujours la charge utile en cas de POST et de PUT.
Dans le cas du POST, vous pouvez créer une entité avec un ID interne ou un UUID. Il est donc logique de renvoyer la charge utile.
De même, dans le cas de PUT, vous pouvez ignorer certains champs de l'utilisateur (des valeurs immuables, par exemple) ou, dans le cas d'un PATCH, les données peuvent également avoir été modifiées par d'autres utilisateurs.
L'envoi des données en tant que données persistantes est toujours une bonne idée et ne nuit définitivement pas. Si l'appelant n'a pas besoin des données retournées, il ne les traitera pas mais utilisera simplement le code de statut. Sinon, ils peuvent utiliser ces données pour mettre à jour l'interface utilisateur.
Ce n'est que dans le cas d'un DELETE que je ne renverrais pas la charge utile et que je ferais un 200 avec un contenu de réponse ou un 204 sans contenu de réponse.
Edit: Merci à quelques commentaires ci-dessous, je reformule ma réponse. Je continue de concevoir les API et de renvoyer les réponses, mais je pense qu'il est logique de qualifier certaines de mes idées de conception.
a) Lorsque je dis à renvoyer la charge utile, je voulais en fait dire à renvoyer les données de la ressource, pas la même charge utile fournie dans la demande. Ex: si vous envoyez une charge de création, je peux créer dans le backend d'autres entités telles que UUID et (peut-être) des horodatages et même certaines connexions (graphiques). Je renverrais tout cela dans la réponse (pas seulement la charge de la requête telle quelle - ce qui est inutile).
b) Je ne renverrais pas les réponses au cas où la charge utile est très grande. J'en ai déjà parlé dans les commentaires, mais ce que je tiens à préciser, c'est que je ferais de mon mieux pour concevoir mes API ou mes ressources de manière à ce que les charges utiles ne soient pas très grandes. J'essayerais de diviser les ressources en entités plus petites et gérables de telle sorte que chaque ressource soit définie par 15 à 20 attributs JSON et non plus grande.
Si l'objet est très volumineux ou si l'objet parent est mis à jour, je vous renverrais les structures imbriquées sous forme de hrefs.
En bout de ligne, je voudrais certainement essayer de renvoyer les données qui ont un sens pour que le consommateur / l'interface utilisateur traite immédiatement et se fassent avec une action d'API atomique plutôt que d'avoir à aller chercher 2 à 5 autres API simplement pour mettre à jour l'interface utilisateur après la création / mise à jour des données.
Les API de serveur à serveur peuvent penser différemment à ce sujet. Je me concentre sur les API qui génèrent une expérience utilisateur.
la source
En vous référant aux normes RFC de lien , vous devez renvoyer le statut 201 (créé) lors du stockage correct de la ressource de demande à l'aide de Post. Dans la plupart des applications, l'identifiant de la ressource est généré par le serveur lui-même. Il est donc recommandé de renvoyer l'identifiant de la ressource créée. Renvoyer l'intégralité de l'objet est la surcharge de la requête Post. La pratique idéale est de renvoyer l’adresse URL de la ressource nouvellement créée.
Par exemple, vous pouvez vous reporter à l'exemple suivant qui enregistre l'objet Employé dans la base de données et renvoie l'URL du nouvel objet ressource créé en réponse.
Ce noeud final restituera la réponse sous la forme:
Statut 201 - CRÉÉ
Header Location → http: // localhost: 8080 / employés / 1
la source
Je ferais une charge utile dans le corps de retour conditionnel à un paramètre HTTP.
Plus souvent qu'autrement, il est préférable de renvoyer une sorte de contenu au consommateur d'API pour éviter les allers-retours inutiles (une des raisons de l'existence de GraphQL.)
En fait, au fur et à mesure que nos applications utilisent de plus en plus de données et plus de distribution, j’essaie de respecter ces consignes:
Ma ligne directrice :
Chaque fois qu'un cas d'utilisation exige un GET immédiatement après un POST ou un PUT, il est préférable de simplement renvoyer quelque chose dans la réponse POST / PUT.
Comment cela est fait, et quel type de contenu renvoyer hors d'un PUT ou d'un POST, c'est spécifique à l'application. Maintenant, il serait intéressant que l'application puisse paramétrer le type de "contenu" dans le corps de la réponse (voulons-nous seulement l'emplacement du nouvel objet, de certains champs ou de l'objet entier, etc.)
Une application peut définir un ensemble de paramètres qu'un POST / PUT peut recevoir pour contrôler le type de "contenu" à renvoyer dans le corps de la réponse. Ou bien, il pourrait coder une sorte de requête GraphQL en tant que paramètre (je peux voir cela utile mais aussi devenir un cauchemar de maintenance.)
De toute façon, il me semble que:
Alors, 1) fais-le, mais 2) reste simple.
Une autre option que j'ai vue consiste à créer des points de terminaison alternatifs (par exemple, / customers pour POST / PUT qui ne renvoie rien dans le corps et / customer_with_details pour POST / PUT à / clients, mais qui renvoie quelque chose dans le corps de la réponse.)
Je voudrais éviter cette approche, cependant. Que se passe-t-il lorsque vous devez légitimement renvoyer un type de contenu différent? Un point de terminaison par type de contenu? Non évolutif ou maintenable.
la source