156 votes

Transactions en repos ?

Je me demande comment vous pouvez mettre en œuvre à la suite de cas d'utilisation en RESTE. Est-il même possible de le faire sans compromettre le modèle conceptuel?

Lire ou mettre à jour de multiples ressources dans le cadre d'une transaction unique. Par exemple, le transfert de 100 $de Bob compte bancaire en Jean.

Aussi loin que je peux dire, la seule façon de mettre en œuvre c'est de la triche. Vous pouvez POSTER à la ressource associée avec un Jean ou Bob et mener à bien l'ensemble de l'opération à l'aide d'une seule opération. Pour autant que je suis concerné, cela rompt avec le RESTE de l'architecture, parce que vous êtes essentiellement de tunneling un appel RPC par la POSTE au lieu de vraiment d'exploitation sur les ressources individuelles.

93voto

Darrel Miller Points 56797

Considérez un scénario de panier shopping RESTful. Le panier est conceptuellement votre wrapper de transaction. De la même façon que vous pouvez ajouter plusieurs éléments à un panier d’achat et ensuite soumettre ce panier pour traiter la commande, vous pouvez ajouter saisie des comptes de Bob pour le wrapper de transaction, puis saisie des comptes de Bill au wrapper. Lorsque toutes les pièces sont en place, alors vous pouvez POST/PUT le wrapper de transaction avec toutes les pièces composant.

63voto

Jon Watte Points 2065

Il y a quelques cas importants qui ne sont pas répondu à cette question, qui je pense est trop mauvais, parce qu'il a un haut classement sur Google pour les termes de recherche :-)

Plus précisément, une belle propertly serait: Si vous postez deux fois (parce que certains cache hiccupped intermédiaire) vous ne devez pas transférer le montant à deux reprises.

Pour arriver à cela, vous créez une transaction comme un objet. Ce pourrait contenir toutes les données que vous savez déjà, et de mettre la transaction dans un état d'attente.

POST /transfer/txn
{"source":"john's account", "destination":"bob's account", "amount":10}

{"id":"/transfer/txn/12345", "state":"pending", "source":...}

Une fois que vous avez cette opération, vous ne pouvez commettre, quelque chose comme:

PUT /transfer/txn/12345
{"id":"/transfer/txn/12345", "state":"committed", ...}

{"id":"/transfer/txn/12345", "state":"committed", ...}

Notez que plusieurs place n'a pas d'importance à ce point; même un GET sur la txn serait de retour à l'état actuel. Plus précisément, la deuxième de METTRE permettrait de détecter que la première était déjà dans l'état approprié, et il suffit de retourner, ou, si vous essayez de le mettre dans les "rolledback" état après qu'il a déjà "commis" de l'etat, vous obtiendrez une erreur, et la transaction validée en arrière.

Tant que vous parlez à une seule base de données ou une base de données avec un moniteur de transactions, ce mécanisme sera effectivement le travail tout aussi bien. Vous pouvez en outre introduire des délais pour les opérations, à même de s'exprimer à l'aide de l'Expiration des en-têtes, si vous vouliez.

35voto

Tuckster Points 155

Dans le RESTE de termes, les ressources sont des noms qui peuvent être traitées avec CRUD (create/read/update/delete) des verbes. Depuis il n'y a pas de "transfert d'argent" le verbe, nous avons besoin de définir une "transaction" des ressources qui peuvent être traitées avec CRUD. Voici un exemple dans HTTP+VARICELLE. La première étape est de CRÉER (méthode HTTP POST) un nouveau vide transaction:

POST /transaction

Retourne un IDENTIFIANT de transaction, par exemple, "1234" et en fonction de l'URL "/transaction/1234". Notez que le fait de tirer ce POST plusieurs fois ne va pas créer la même opération avec de multiples Identifiants et évite aussi l'introduction d'un état "en attente". De plus, le POST ne peut pas toujours être idempotent (une exigence de REPOS), il est donc conseillé de minimiser les données dans les Messages.

Vous pouvez laisser la génération de l'ID de la transaction du client. Dans ce cas, vous pouvez publier /transaction/1234 pour créer de transaction "1234" et le serveur renvoie une erreur si elle existait déjà. Dans la réponse d'erreur, le serveur peut retourner un actuellement inutilisés ID avec une URL. Ce n'est pas une bonne idée d'interroger le serveur pour une nouvelle ID avec une méthode GET, depuis l'OBTENIR ne devriez jamais modifier l'état du serveur et de la création/la réservation d'un nouvel ID serait de modifier l'état du serveur.

Prochaine étape, nous avons UPDATE (METTRE HTTP méthode) l'opération avec toutes les données, implicitement de s'engager:

PUT /transaction/1234
<transaction>
  <from>/account/john</from>
  <to>/account/bob</to>
  <amount>100</amount>
</transaction>

Si une transaction dont l'ID est "1234" a été MIS de l'avant, le serveur donne une réponse d'erreur, sinon une réponse OK et une URL pour afficher la transaction terminée.

NB: dans /compte/jean , "jean" devrait vraiment être John's numéro de compte unique.

20voto

13ren Points 3672

La grande question, le RESTE est principalement expliqué par la base de données comme exemples, où quelque chose est stockée, mise à jour, la récupération, l'supprimé. Il y a peu d'exemples comme celui-ci, où le serveur est censé traiter les données d'une certaine façon. Je ne pense pas que Roy Fielding inclus dans sa thèse, qui a été basé sur http, après tout.

Mais il ne parle de "representational state transfer" comme une machine d'état, avec des liens en mouvement à l'état suivant. De cette façon, les documents (les représentations) de garder une trace de l'état du client, au lieu du serveur à avoir à le faire. De cette façon, il n'y a pas de client état, que l'état en termes de lien qui vous êtes.

J'ai pensé à ce sujet, et il me semble raisonnable que, pour obtenir le serveur pour traiter quelque chose pour vous, lorsque vous téléchargez, le serveur va créer automatiquement les ressources connexes, et de vous donner les liens (en fait, il n'aurait pas besoin de créer automatiquement: il pourrait juste vous dire les liens, et il ne les créer quand et si vous les suivez - paresseux création). Et aussi de vous donner des liens pour créer de nouvelles ressources connexes - une ressource liés a la même URI, mais est plus (ajoute un suffixe). Par exemple:

  1. Vous téléchargez (POST) la représentation de la notion de transaction avec toutes les informations. Cela ressemble à un appel RPC, mais c'est vraiment de la création de la "transaction proposée des ressources". e.g URI: /transaction Pépins sera la cause de plusieurs de ces ressources à être créés, chacun avec un URI différent.
  2. Le serveur de la réponse de l'etat à la création de la ressource URI, sa représentation - ce qui inclut le lien (URI) pour créer la ressource connexe d' un nouveau "transaction validée ressources". D'autres ressources connexes sont le lien pour supprimer la transaction proposée. Ce sont des états dans l'état de la machine, le client peut suivre. Logiquement, ceux-ci font partie de la ressource qui a été créé sur le serveur, au-delà de l'information que le client fourni. e.g Uri: /transaction/1234/proposed, /transaction/1234/committed
  3. Vous POST le lien pour créer la "transaction validée ressources", ce qui crée de la ressource, en changeant l'état du serveur (les soldes des deux comptes)**. De par sa nature, cette ressource ne peut être créé qu'une seule fois, et ne peut pas être mis à jour. Par conséquent, des problèmes de commettre de nombreuses transactions ne peut pas se produire.
  4. Vous pouvez OBTENIR ces deux ressources, pour voir ce que leur état est. En supposant qu'un POST peut changer d'autres ressources, la proposition serait désormais être marqué comme "commis" (ou peut-être pas disponible à tous).

Ceci est similaire à la façon dont les pages web fonctionnent avec la version finale page web en disant: "êtes-vous sûr de vouloir faire cela?" Final page web est lui-même une représentation de l'état de la transaction, qui comprend un lien pour aller vers l'état suivant. Non seulement les transactions financières; aussi (par exemple) puis un aperçu de s'engager sur wikipédia. Je suppose que la distinction en RESTE, c'est que chaque étape de la séquence d'états a un nom explicite (URI).

Dans la vie réelle des opérations et des ventes, il y a souvent des physiques différents documents pour les différentes étapes d'une transaction (proposition, commande, réception, etc). Encore plus pour l'achat d'une maison, avec le règlement..

Otoh, que C'est comme jouer avec une sémantique pour moi; je ne suis pas à l'aise avec la nominalisation de conversion les verbes en noms pour faire il Reposante, "parce qu'il utilise des noms (Uri) au lieu de verbes (appels RPC)". c'est à dire le nom de la "transaction validée ressource" au lieu du verbe "commettre cette transaction". Je suppose que l'un des avantages de la nominalisation est vous pouvez vous référer à la ressource par nom, au lieu d'avoir besoin de le spécifier dans une autre façon (comme le maintien de l'état de session, de sorte que vous savez ce que "cette" transaction...)

Mais la question importante est: Quels sont les avantages de cette approche? c'est à dire De quelle façon est-ce RESTE de style mieux que le style RPC? Est une technique qui est génial pour les pages web également utile pour le traitement de l'information, au-delà de stocker/récupérer/mise à jour/supprimer? Je pense que le principal avantage de REPOS est l'évolutivité; un seul aspect de l'est n'ayant pas besoin de maintenir l'état explicitement (mais il est implicite dans l'URI de la ressource, et la prochaine états comme des liens dans sa représentation). En ce sens, il contribue. Peut-être cela contribue à la dispersion/pipeline trop? Otoh, que seul l'utilisateur en transaction spécifique, donc il n'y a aucun avantage à la mise en cache afin que d'autres puissent le lire, la grande victoire pour http.

10voto

TheSoftwareJedi Points 15921

Vous devrez rouler votre propre type de « transaction id » de gestion de tx. Il serait donc 4 appels :

Vous devrez gérer le stockage des actions dans une DB (si charge équilibrée), ou en mémoire ou tel, puis manipulation commit, rollback, délai d’attente.

Pas vraiment une journée reposante dans le parc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X