web-dev-qa-db-fra.com

Choisissez entre http 401 et 409

J'ai deux API pour suivre et ne plus suivre un utilisateur.

domain/uid/follow    (http POST)       to follow user
domain/uid/follow    (http DELETE)     to unfollow user

Il suit l'utilisateur et répond avec le code http 200. Lorsque l'utilisateur essaie de suivre à nouveau (utilisateur déjà suivi) je réponds avec 401.

Questions:

1 - Dois-je répondre en cas de conflit 401 non autorisé ou 409?

2 - Même chose lorsque l'utilisateur ne suit pas quelqu'un et essaie de le désabonner.

Modifier:

Je n'utilise pas d'API unique pour basculer follow/unfollow comportement. J'ai 2 API distinctes pour les deux actions.

Je n'ai aucune raison particulière de répondre par erreur. Le seul endroit où il est utilisé est les tests automatisés des API pour vérifier qu'un utilisateur n'est pas suivi deux fois.

13
Shaharyar

Techniquement, cela dépend de la méthode HTTP que vous utilisez. Je vous suggère d'utiliser PUT car si vous le faites, cette argumentation fonctionne très bien:

Si quelqu'un veut suivre un autre utilisateur et qu'il le fait déjà, c'est très bien, non? Il en va de même pour le désabonnement. Donc renvoie toujours 200 .

Ce comportement est appelé idempotence. Voir cette explication pour plus d'informations.


Si vous optez pour POST, vous devez techniquement créer une ressource selon les conventions HTTP. La création d'une ressource n'est pas idempotente et votre interface ne le pourrait pas non plus. Si vous suivez cette convention, vous devez renvoyer le statut 409 Conflit ou 422 Unprocessable Entity sur les demandes de double suivi et de non-suivi. Donner la raison plus en détail dans un corps de réponse d'erreur est une bonne pratique; cela aide énormément vos consommateurs d'API.

Cependant, la RFC 7231 (HTTP 1.1) ne vous oblige pas à toujours créer une ressource; un idempotent POST est donc aussi une solution valide.


Remarque: 401 signifie Unauthorized. Cela signifie que la demande ne fournit pas d'informations d'identification ou que les informations d'identification fournies sont invalides . Cependant, je suppose que vous avez validé avec succès les informations d'identification avant même d'essayer de faire le suivi/désabonnement. Ainsi, répondre avec 401 n'a absolument aucun sens dans cette situation. 403 Forbidden est farfelu et aussi peu applicable (mais toujours meilleur que 401).

42
marstato

Ne traduisez pas les erreurs métier en codes d'état HTTP. Les codes d'état sont destinés à être lus par le client HTTP, pas par votre domaine ni par l'utilisateur lui-même. Nous utiliserons le corps de réponse pour communiquer avec ces deux-là. Si nous devons envoyer un message, nous l'envoyons dans le corps de la réponse.

Création du suivi 1

POST /domain/uid/follow HTTP/1.1
...
HTTP/1.1 201 Created
Date: Fri, 20 Dec 2017 14:30:00 GMT
Content-Type: application/json
Location: /domain/uid/follow/123456

Duplication du suivi 2

POST /domain/uid/follow HTTP/1.1
...
HTTP/1.1 409 Conflict
Date: Fri, 20 Dec 2017 14:30:00 GMT
Content-Type: application/json
Content-Length: 100
{"message":"already following Shaharyar!"}

Nous pouvons également utiliser des en-têtes de réponse personnalisés.

MyApplication-error: AlreadyFollowingUserError

non suivi

2 - Même chose lorsque l'utilisateur ne suit pas quelqu'un et essaie de le désabonner.

Ce deuxième cas est légèrement différent.

Si nous essayons de supprimer une ressource qui n'existe pas

DELETE /domain/uid/follow HTTP/1.1
...
HTTP/1.1 404 Not Found
Date: Fri, 20 Dec 2017 14:30:00 GMT
Content-Type: application/json
Content-Length: 1000
MyApplication-error: ResourceNotFound
{"message":"resource not found"}

Ou comme @K. Alan Bates a commenté (merci Alan), nous pourrions rendre l'opération idempotente, dès que l'URI que nous demandons est toujours accessible.

DELETE /domain/uid/follow HTTP/1.1
...
HTTP/1.1 204 No content
Date: Fri, 20 Dec 2017 14:30:00 GMT
Content-Type: application/json
Content-Length: 100

J'ai choisi 204 pour plus de simplicité. Ce pourrait être 200 ou 202.

Dans tous les cas, nous ne répondons pas avec 401 Unauthorized sauf indication contraire de notre service de sécurité.


1: Modifier - Idéalement, après une nouvelle création de ressource, nous devrions répondre avec le nouvel emplacement de ressource (uri) et le code d'état 201

2: Modifier - Le code d'état ici dépendra de la méthode. Si nous POST nous demandons une nouvelle ressource. Si elle existe déjà, le conflit 409 est ok. Si la demande crée une nouvelle ressource, 201. Si nous envoyons un PUT, 200 ou 204 sont ok. Cependant, l'idempotence pourrait simplifier tout cela

19
Laiv

Basé sur le RFC mentionné dans le commentaire de Willem Renzema sur la réponse de marstato, je pense que l'approche la plus propre est d'avoir votre POST créer une nouvelle ressource. Je suppose que vous pourriez faites quelque chose de simple tel que "domaine/uid/suivi" si vous ne voulez pas avoir à les rechercher dans votre client. Ensuite, lorsque vous souhaitez vous désabonner, vous supprimez cette ressource. Si un autre message vient pour l'URI de suivi quand il existe déjà, vous renvoyez 303 et renvoyez l'en-tête "Content-Location" avec la ressource "suivante".

Un avantage secondaire de la création des ressources "suivantes" est que vous pouvez l'utiliser pour créer une liste de ce qu'un utilisateur suit.

2
JimmyJames