Les Transactions dans le 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 le compte en banque de Jean de compte.
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.
Vous devez vous connecter pour publier un commentaire.
Envisager un séjour panier scénario. Le panier est conceptuellement votre transaction wrapper. De la même manière que vous pouvez ajouter plusieurs éléments à un panier et de le soumettre ensuite au panier pour le traitement de la commande, vous pouvez ajouter le compte de Bob a l'entrée de la transaction wrapper et le projet de Loi compte de l'entrée de l'emballage. Lorsque toutes les pièces sont en place, vous pouvez publier/METTRE la transaction wrapper avec toutes les pièces composantes.
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.
Une fois que vous avez cette opération, vous ne pouvez commettre, quelque chose comme:
Noter 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 il est déjà "commis" de l'etat, vous obtiendrez une erreur, et la transaction validée en arrière.
Aussi longtemps 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.
En RESTE 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) une nouvelle vide transaction:
Cela 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 pourriez quitter 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 mise à JOUR (MIS méthode HTTP) de la transaction avec toutes les données, implicitement commettre:
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.
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, vous êtes sur.
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 nouveau ressources connexes - une ressource liés a la même URI, mais est plus (ajoute un suffixe). Par exemple:
/transaction
Pépins sera la cause de plusieurs de ces ressources à être créés, chacun avec un URI différent.
/transaction/1234/proposed
,/transaction/1234/committed
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 (son 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 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.
Si vous restez en arrière, pour résumer la discussion ici, il est assez clair que le REPOS n'est pas approprié pour de nombreuses Api, en particulier lorsque le client-serveur de l'interaction est intrinsèquement dynamique, car il est non triviale des transactions. Pourquoi sauter à travers tous les cerceaux suggéré, pour client et serveur à la fois, dans l'ordre de manière affectée suivre quelque principe que ce n'est pas le problème? Une meilleure principe est de donner au client la plus simple, la plus naturelle, de façon productive à composer avec l'application.
En résumé, si vous êtes vraiment faire beaucoup de transactions (types, pas les instances) dans votre application, vous ne devriez pas être la création d'une API RESTful.
Je me rends à l'écart de ce sujet depuis 10 ans. De retour, je ne peux pas croire que la religion se faisant passer pour de la science que vous wade lorsque vous google reste+fiable. La confusion est mythique.
Je voudrais diviser cette vaste question en trois:
Ceci est important car il permet à toutes les demandes ultérieures être entièrement idempotent, dans le sens que si elles sont répétées n fois qu'ils retournent le même résultat et cause plus rien à se produire. Le serveur stocke toutes les réponses à l'encontre de l'action de l'id, et si elle voit la même demande, elle rejoue la même réponse. Un un traitement plus complet du modèle est dans ce google doc. Le doc suggère une mise en œuvre qui, je crois(!), suit largement le REPOS des directeurs d'école. Des Experts va sûrement me dire comment elle viole les autres. Ce modèle peut être utilement employée pour n'importe quel dangereux appel à votre web-service, qu'il existe ou non en aval des opérations concernées.
Votre exigence est fondamentale. Ne laissez pas les gens vous disent que votre solution n'est pas casher. De juger de leurs architectures, à la lumière de la façon dont bien, et de façon simple, ils résoudre votre problème.
Vous auriez à rouler votre propre "id de la transaction de type" tx de gestion. Il serait donc 4 appels:
Vous aurez à gérer le stockage de l'action dans une DB (si la charge équilibrée) ou dans la mémoire ou un tel, commit, rollback, délai d'attente.
Pas vraiment une bonne journée dans le parc.
Tout d'abord transférer de l'argent n'est rien que vous ne pouvez pas le faire en une seule ressource appel. L'action que vous voulez faire est d'envoyer de l'argent. Si vous ajoutez un transfert d'argent de personne-ressource pour le compte de l'expéditeur.
Fait. Vous n'avez pas besoin de savoir que c'est une opération qui doit être atomique, etc. Vous venez de transférer de l'argent aka. envoyer de l'argent à partir d'Un a à un point B.
Mais pour les rares cas ici, une solution générale:
Si vous voulez faire quelque chose de très complexe impliquant de nombreuses ressources dans un contexte défini avec beaucoup de restrictions qui fait traverser le ce vs pourquoi barrière d'affaires (vs la mise en œuvre de connaissances) vous avez besoin de transférer de l'état. Depuis le RESTE doit être apatrides vous en tant que client de besoin pour le transfert de l'etat autour.
Si vous transférez de l'état vous avez besoin de cacher l'information à l'intérieur de la part du client. Le client ne doit pas connaître d'information interne qu'à la mise en œuvre mais ne portent pas d'information pertinente en termes de business. Si ces informations n'ont aucune valeur commerciale de l'état doivent être chiffrés et une métaphore comme un jeton, passer ou quelque chose a besoin d'être utilisée.
De cette façon, on peut passer l'état interne autour et à l'aide de chiffrement et de signature, le système peut encore être sécurisé et son. Trouver le bon abstraction pour le client pourquoi il se passe autour de l'état de l'information est quelque chose qui est à la hauteur du design et de l'architecture.
La vraie solution:
Souvenir RESTE est en train de parler HTTP et HTTP livré avec le concept de l'utilisation de cookies. Ces cookies sont souvent oubliés quand les gens parlent de l'API REST et les flux de travail et les interactions couvrant de multiples ressources ou des demandes.
Rappelez-vous ce qui est écrit dans le Wikipedia à propos des cookies HTTP:
Donc, fondamentalement, si vous avez besoin de passer sur l'état, l'utilisation d'un cookie. Il est conçu exactement pour la même raison, il est HTTP et par conséquent, il est compatible de REPOS par le design :).
La meilleure solution:
Si vous parlez à un client d'effectuer un flux de travail impliquant de multiples demandes que vous l'habitude de parler de protocole. Toute forme de protocole est livré avec un ensemble de conditions préalables pour chaque étape potentielle comme effectuer Une étape avant que vous pouvez faire B.
C'est naturel, mais de l'exposer protocole pour les clients, tout devient plus complexe. Pour l'éviter il suffit de penser ce que nous faisons lorsque nous avons à faire des interactions complexes et des choses dans le monde réel... . Nous utilisons un Agent.
À l'aide de la métaphore de l'Agent, vous pouvez fournir une ressource qui peut effectuer toutes les étapes nécessaires pour vous et stocker l'attribution /instructions qu'il agit dans sa liste (si nous pouvons utiliser des POST sur l'agent ou d'une "agence").
Un exemple complexe:
L'achat d'une maison:
Vous devez prouver votre crédibilité (comme la fourniture de votre dossier de police entrées de), vous devez vous assurer que les détails financiers, vous avez besoin d'acheter la maison à l'aide d'un avocat et d'un tiers de confiance stockage de fonds, à vérifier que la maison appartient aujourd'hui à vous et à ajouter les acheter des choses à votre dossier fiscal etc. (juste comme exemple, certaines étapes peuvent être mauvais ou quoi que ce soit).
Ces étapes peut prendre plusieurs jours pour être achevé, certains peuvent être effectuées en parallèle etc.
Pour ce faire, vous venez de donner à l'agent de la tâche acheter maison comme:
Fait. L'agence vous envoie une référence pour vous que vous pouvez utiliser afin de voir et de suivre le statut de ce poste, et le reste est fait automatiquement par les agents de l'agence.
Penser à un bug tracker par exemple. Fondamentalement, vous signaler le bug et on peut utiliser le bug id pour vérifier ce qui se passe. Vous pouvez même utiliser un service à l'écoute des changements de cette ressource. Mission Réalisée.
Je pense que dans ce cas, il est tout à fait acceptable pour briser la théorie pure du REPOS dans cette situation. En tout cas, je ne pense pas qu'il y est quelque chose de vraiment en RESTE, qui dit que vous ne pouvez pas toucher les objets dépendants dans les affaires les cas qui le nécessitent.
Je pense vraiment que ça ne vaut pas le supplément de cerceaux de vous sauter à travers pour créer un gestionnaire de transactions, quand vous pourriez tirer parti de la base de données pour le faire.
Vous ne devez pas utiliser côté serveur transactions en RESTE.
Un de le RESTE les contraintes:
Le seul Réparateur est de créer une opération redo log et le mettre dans le client de l'état. Avec la demande le client envoie les fichiers redo log et le serveur répète l'opération et
Mais c'est peut-être plus simple d'utiliser une session sur le serveur en fonction de la technologie qui prend en charge côté serveur de transactions.
Je crois que ce serait le cas de l'utilisation d'un identifiant unique généré sur le client pour s'assurer que la connexion hoquet implique pas dans une duplicité enregistré par l'API.
Je pense que l'utilisation d'un client généré champ GUID avec le transfert de l'objet et de s'assurer que le même GUID n'a pas été réinséré nouveau serait une solution plus simple à la banque de transfert de matière.
Ne sais pas à propos des scénarios plus complexes, telles que la sclérose en billet d'avion, la réservation ou de la micro-architectures.
J'ai trouvé un article sur ce sujet, concernant les expériences de traitant de la transaction, l'atomicité de services RESTful.
Dans le cas simple (sans ressources distribuées), vous pourriez considérer la transaction comme une ressource, où l'acte de création de l'atteinte de l'objectif final.
Donc, pour le transfert entre les
<url-base>/account/a
et<url-base>/account/b
, vous pouvez poster à la suite de<url-base>/transfer
.Cela permettrait de créer un nouveau transfert de ressources et de retour de la nouvelle url du transfert - par exemple
<url-base>/transfer/256
.Au moment du post, ensuite, le "réel", l'opération est effectuée sur le serveur, et le montant retiré d'un compte à un autre.
Ceci, cependant, ne couvre pas une transaction distribuée (si, par exemple " une " est tenu à une banque derrière un service, et 'b' est tenu dans une autre banque derrière un autre service) - autres que de dire "essayer de phrase toutes les opérations d'une manière qui ne nécessite pas de transactions distribuées".
Je suppose que vous pourriez inclure le TAN dans l'URL/ressources:
Juste une idée.