2017-09-07 3 views
1

REST POST est utilisé pour créer des ressources.Comment gérer la perte de connectivité réseau au milieu de la requête REST POST?

Disons que nous avons des ressources url « http://example.com/cars »

Nous voulons créer une nouvelle voiture. Nous POST à ​​"http://example.com/cars" avec charge utile JSON contenant les propriétés de la voiture (couleur, poids, modèle, etc).

serveur reçoit la demande, crée une nouvelle voiture, envoie une réponse sur le réseau.

À ce stade réseau échoue (disons que le routeur cesse de fonctionner correctement et ignore chaque paquet).

Le client échoue avec le délai TCP (90 secondes). Le client n'a aucune idée si la voiture a été créée ou non. De même, le client n'a pas reçu l'ID de ressource de la voiture, il ne peut donc pas le récupérer pour vérifier s'il a été créé.

Maintenant quoi? Comment gérez-vous cela? Vous ne pouvez pas simplement réessayer de créer car la nouvelle tentative créera simplement un doublon (ce qui est incorrect).

Répondre

0

REST POST est utilisé pour créer des ressources.

HTTP POST est utilisé pour beaucoup de choses. REST ne s'en soucie pas particulièrement; il veut juste des ressources qui supportent une interface uniforme, et hypermédia.

A ce réseau de points échoue

Bummer!

Maintenant quoi? Comment gérez-vous cela? Vous ne pouvez pas simplement réessayer de créer, car réessayer créera simplement un doublon (ce qui est mauvais).

Ceci est une préoccupation de messagerie générale, pas directement liée à REST. La solution la plus courante consiste à utiliser le modèle Idempotent Receiver.En bref, vous devez définir vos messages afin que le destinataire dispose de suffisamment d'informations pour reconnaître la requête comme quelque chose qui a déjà été fait.

Idéalement, ceci est pris en charge au business level.

Les collections de valeurs idempotentes sont souvent simples; nous avons juste besoin de penser définit, plutôt que listes.

Les collections d'entités les plus complexes sont plus complexes; Si la demande inclut un identifiant pour la nouvelle entité, ou si nous pouvons en calculer un à partir des données fournies, alors nous pouvons considérer notre collection comme un hachage.

Si aucune de ces approches ne convient, alors il y a une autre possibilité. Au lieu d'effectuer une mutation idempotente de la collection, nous rendons idempotente la mutation de la collection elle-même. Pensez à "comparer et échanger" - nous encodons dans l'information de demande qui identifie l'état actuel de la collection; Cet état est toujours actuel lorsque la demande arrive, puis la mutation est appliquée. Si la condition ne tient pas, alors la requête devient un no-op. En traduisant cela en HTTP, nous apportons une petite modification au protocole de mise à jour de la ressource de collection. D'abord, nous obtenons la représentation actuelle; et dans les métadonnées, le serveur fournit validators qui peut être utilisé dans des demandes subséquentes. Après avoir obtenu le validateur, le client évalue la représentation actuelle de la ressource pour déterminer si elle doit être modifiée. Si le client décide d'effectuer une modification, il soumet la modification avec un If-Match ou un en-tête If-Unmodified-Since, y compris le validateur. Le serveur, avant de traiter les demandes, considère alors le validateur, abandonnant immédiatement la demande avec 412 Precondition Failed.

Ainsi, si une demande de changement d'état conditionnel est perdue, le client peut, à sa propre discrétion, répéter la demande sans se soucier que le serveur ne comprenne pas l'intention du client.

0

Réessayez un nombre limité de fois, avec des délais croissants entre les tentatives, et assurez-vous que la transaction concernée est idempotente.

car une nouvelle tentative créera un doublon (ce qui est incorrect).

Il est en effet, et il a besoin de fixation, voir ci-dessus. Il devrait être impossible dans votre système de créer deux entrées avec les mêmes attributs. Ceci est facilement accompli au niveau de la base de données. Vous pouvez atteindre l'idempotence en faisant en sorte que la transaction renvoie la même chose, que l'entrée existait déjà ou qu'elle ait été créée récemment. Ou alors il suffit de renvoyer EXISTS si l'entrée existe déjà, et ajustez votre client en conséquence.