Si les transactions sur REST sont irréalisables, comment REST peut-il être vraiment utile?

En examinant REST une des premières choses que quelqu’un remarquera probablement, il n’y a pas de sémantique de transaction définie, certains disent que cela est implicitement contre ce que REST est, tandis que d’autres disent que toute tentative de le faire .

Mais disons pour argument que REST est devenu un choix populaire «api», et chaque site de l’univers a commencé à exposer des points d’entrée reposants.

Comment sont-ils exactement utilisables sans comportement de transaction (et je parle non compensateur)? Comme il me semble que l’un des avantages de REST réside dans le fait qu’il décompose les composants des données, cela les amènerait à demander aux clients intelligents de composer des données (et d’append et d’ajuster ces données composées) à partir de plusieurs services. Mais si je ne peux pas apporter mes modifications à cette composition de données de manière atomique et isolée, l’utilisation de REST devient inutile.

Au fur et à mesure que le temps passe et que le besoin d’exposition de données sérieuses arrive, nous voulons quelque chose qui est: Simple (REST y gagne) et supporte le comportement transactionnel afin que nous puissions manipuler ces données de manière fiable.

Maintenant, j’ai lu un argument spécifique à plusieurs resockets dans ma recherche, et son lien avec la façon dont nous sums censés penser aux transactions dans REST, et l’exemple donné est le panier d’achat, où vous avez implicitement de l’isolement parce que le panier C’est le tien.

Cependant, je ne suis pas d’accord avec cet argument. Premièrement, l’isolation d’un panier est tout simplement commode, ce n’est pas un isolement de transaction. Que se passe-t-il si je fais simultanément une opération sur mon panier alors que à partir de cela? Je ne m’attendrais pas à ce que la partie lecture de mon application voie des données «toujours en transaction».

Sans compter que toutes les modifications de données n’ont pas un modèle de transaction implicite, ce n’est pas le cas pour les transactions sur plusieurs services.

Il me semble que les transactions doivent avoir lieu et qu’elles doivent se dérouler d’une manière qui permette aux appels REST réels d’être ignorants (en ajoutant une charge importante non, mais en ajoutant des en-têtes corrects).

J’ai lu quelques suggestions sur la façon dont un modèle de transaction peut être créé sur REST, et certaines des spécifications écrites semblent être très récentes.

Y a-t-il de vraies pensées à ce sujet? ne devrait-il pas y avoir quelque chose de plus que le REST pour que la nature simpliste de REST puisse être exploitée contre une manipulation solide des données (transactions «acides»).

Si ce n’est pas le cas, est-ce qu’on s’attend à ce que l’on mette vraiment la barre très haut et dise aux développeurs de services que s’ils veulent interagir dans un monde de données pur, ils doivent prendre en charge quelque chose ou pire encore, essayer de construire leur propre support de transaction personnalisé en quelque chose comme REST, rendant chaque service non standard et brisant toute la puissance de REST?

Merci d’avance pour toute reflection.


Modifier, ajouté un bref scénario:

Imaginez un formulaire client qui gère la création d’un album, pour plus de commodité sur cet album, plutôt que de demander à l’utilisateur de donner l’URI pour la ressource artiste, il peut choisir parmi une liste d’artistes (probablement tirée du catalogue d’artistes) .

Par souci de convivialité, le client peut écrire le nom de l’artiste manuellement afin de créer un artiste “inline”. Dans le scénario de publication, le code client comprend cela et avant d’envoyer la demande de création si l’artiste existe déjà, si c’est le cas, obtient l’URI pour cet artiste, sinon il crée l’artiste et obtient les artistes uri.

Le code client continue alors à créer l’album, il s’agit du client le plus intelligent, il n’est pas placé juste au-dessus de REST et affiche «dumbly», mais a plutôt une interaction qui gère la logique REST plus pure.

Cependant, dans ce scénario, il serait bon de garantir que l’artiste n’est pas créé à moins que l’album ne soit, étant donné que l’artiste est créé en premier.

Ce n’est pas aussi “critique” qu’une transaction impliquerait, mais cela définit un ensemble de travail que le code client préférerait être en une seule opération (après tout, cela fait ressembler cette opération à une seule opération pour l’utilisateur).

Le seul conseil que j’ai vu pour ce scénario consiste à demander au client d’effectuer une action de compensation en cas d’échec de la création de l’album et d’appeler spécifiquement à supprimer l’artiste. Mais cela semble problématique, car le client suppose que l’artiste était isolé, aussi improbable que cela puisse être, que se passe-t-il si un autre client a déjà «vu» cet artiste et lui assigne une responsabilité?

Ce sont mes préoccupations concernant les changements de données, et bien qu’il y ait certainement d’autres lacunes (qui dit que l’artiste ne peut pas être supprimé à une date ultérieure), ces actions ne sont PAS transparentes (les actions ne sont pas automatisées par le client, mais quelque chose qu’un utilisateur a spécifiquement demandé).

J’espère que cela aide à éclairer le sujet.

    Je vais supposer que lorsque vous parlez de transactions, vous parlez d’un protocole dissortingbué à deux phases .

    Si je comprends bien, vous essayez de comprendre comment nous pourrions utiliser REST pour effectuer des opérations sur plusieurs systèmes si REST ne peut pas prendre en charge les transactions sur des requêtes REST distinctes. Le problème est que vous faites une hypothèse potentiellement erronée selon laquelle nous devrions utiliser les transactions pour atteindre la cohérence. Quel prix payons-nous pour les utiliser et quelles alternatives existent?

    Pat Helland, qui travaillait pour Amazon et est maintenant chez Microsoft, a écrit un article Life sur les transactions dissortingbuées . Dans l’article, l’auteur fait la déclaration suivante:

    Malheureusement, les programmeurs qui s’efforcent de résoudre des objectives commerciaux tels que le commerce électronique, la gestion de la chaîne d’approvisionnement, les applications financières et les applications de soins de santé doivent de plus en plus réfléchir à la mise à l’échelle sans transactions dissortingbuées. Ils le font parce que les tentatives d’utilisation des transactions dissortingbuées sont trop fragiles et peu performantes.

    Son article explore des solutions alternatives aux transactions dissortingbuées qui évoluent et fonctionnent bien.

    Peut-être que REST réussira car il ne supporte pas les transactions. Voici une citation de Roy Fielding, le gars qui a inventé le terme REST

    Si vous avez besoin d’un protocole de transaction dissortingbué, alors comment pouvez-vous dire que votre architecture est basée sur REST? Je ne peux tout simplement pas voir comment une situation (d’utilisation de l’état de l’application RESTful sur le client et de l’hypermédia pour déterminer toutes les transitions d’état) peut se présenter dans un autre cas où le client doit indiquer comment gérer ses propres ressources.

    … pour l’instant, je considère que la “transaction de repos” est un oxymoron.

    Cela provient d’un message sur la liste REST-discuss du 9 juin 2009. Je ne peux pas fournir de lien car les groupes Yahoo sont inutiles.

    Si vous voulez des transactions dans une application ReST, à la fonction API ReST, c’est généralement parce que vous avez toujours votre gars sur le Web service web.

    Regardons les choses autrement.

    Soap googles on: Ouvrez une transaction, créez un enregistrement client, créez un enregistrement de commande, validez une transaction.

    ReST googles on: Demandez au serveur quoi faire. Le serveur dit “créer une ressource client”, donc POST / clients. Serveur dit “créer maintenant une commande si vous le souhaitez”, le client crée la commande en suivant le formulaire.

    Dans ReST, le protocole d’application est exprimé en termes de ressources créées et manipulées, et non en termes de données comportant des limites de transaction.

    Si vous voulez avoir une transaction longue qui couvre toutes ces opérations, c’est le serveur qui décide de l’initier, pas le client.

    Vous pouvez toujours implémenter de longues transactions sur le serveur. Si vous tentez d’obtenir des transactions du côté client, vous supposez que le client connaît déjà toutes les opérations qu’il va exécuter et les limites de transaction qui existent entre ces opérations. Si c’est ce que vous attendez du client, vous avez déjà renoncé à la nature tardive, liée à l’hypermédia, d’une architecture de repos.

    En effet, si vous ne faites pas de ReST et que vous essayez de vous connecter à RPC via http, vous n’aurez pas de problème avec les transactions.

    Je pense que la plupart des actions qui nécessitent normalement des transactions peuvent être retravaillées sans elles.

    Par exemple, le virement bancaire classique. Supposons que je veuille transférer 100 $ du compte A à B:

     Commencer la transaction
       / Débit A, 100 $  
       / Crédit B, 100 $
     Transaction Commit
    

    Cela pourrait être retravaillé comme:

      / Transfert A, B, 100 $  
    

    De cette façon, le serveur peut le faire en deux étapes, mais l’action du client est une opération atomique unique qui a un sens logique.

    Je suis sûr qu’il y a beaucoup d’exemples où il est plus pratique de faire un ensemble d’opérations (et je suis curieux de savoir ce que les gens peuvent faire pour les résoudre), mais je retravaille généralement les choses de cette manière.

    Une opération REST peut démarrer une transaction, effectuer plusieurs opérations de firebase database ou autres opérations transactionnelles, puis valider ou annuler – tout cela dans le cadre d’une transaction.

    Ce que REST ne peut pas faire est d’être autre que la racine d’une transaction. Vous ne pouvez pas démarrer une transaction, puis effectuer deux opérations REST et une opération de firebase database, puis les valider toutes ensemble. C’est comme la situation des services Web ASMX dans .NET. Ils peuvent être à la base d’une transaction, mais c’est tout. Ils ont été couronnés de succès pendant des années, jusqu’à ce que WCF soit introduit, supportant WS-Transactions. Même aujourd’hui et en utilisant WCF, la plupart des opérations de service Web n’ont pas besoin d’être transactionnelles dans le sens où vous vous posez.

    C’est un sujet intéressant. Comme vous l’avez mentionné, SOAP a déjà ce type de fonctionnalité, mais il a fallu de nombreuses années avant que SOAP ne parvienne à maturité au point que les gens envisagent de faire de la sécurité et des transactions réelles avec elle. Avant cela, c’était CORBA.

    Les diverses extensions de haut niveau de SOAP, y compris la sécurité et les transactions, ont demandé beaucoup de travail à de nombreuses personnes. Cela ne va pas arriver à REST du jour au lendemain, et cela peut ne jamais arriver du tout.

    Je pense qu’une grande partie de la popularité actuelle de REST est une sorte de réaction contre les implémentations SOAP mal conçues et trop compliquées, ce qui est dommage, car SOAP ne doit pas nécessairement être comme ça. Comme pour toute autre chose, il faut un bon design pour que ça marche bien.

    Je pense que les transactions utilisant REST sont réellement réalisables. Considérez une transaction comme une ressource que vous pouvez créer (démarrer), modifier (publier des modifications via) et supprimer (valider, annuler). Les modifications envoyées à la transaction n’ont pas besoin de modifier l’état global tant que la transaction n’a pas été validée et, lors de la validation, vous pouvez appliquer toutes les règles de cohérence d’état globales dont vous avez besoin. La ressource de transaction serait bien sûr protégée par des règles d’autorisation.

    Vous avez déjà mentionné l’illustration commune de ce concept:

    Maintenant, j’ai lu un argument spécifique à plusieurs resockets dans ma recherche, et son lien avec la façon dont nous sums censés penser aux transactions dans REST, et l’exemple donné est le panier d’achat, où vous avez implicitement de l’isolement parce que le panier C’est le tien.

    Cependant, je ne suis pas d’accord avec cet argument. Premièrement, l’isolation d’un panier est tout simplement commode, ce n’est pas un isolement de transaction. Que se passe-t-il si je fais simultanément une opération sur mon panier alors que à partir de cela? Je ne m’attendrais pas à ce que la partie lecture de mon application voie des données «toujours en transaction».

    Pourquoi ne pas autoriser la visualisation de la transaction? Tant que vous le présentez tel quel, une liste des modifications en attente, il est utile de fournir cette fonctionnalité. Mais si vous ne voulez pas qu’il soit visible, vous pouvez désactiver GET sur la ressource.

    Jetez un coup d’oeil à l’ API OpenStreetMap . Je pense que c’est une sorte de “REST” et qu’il fournit des “transactions” – appelées “changesets”. Est-ce ce dont vous avez besoin?

    En fait, les transactions dans REST fonctionnent de la même manière que les transactions sont censées fonctionner dans les services SOAP traditionnels.

    Les transactions de type RPC, dans lesquelles le client émet une commande “begin transaction” (ou une opération qui commence implicitement mais ne valide pas une transaction), suivie d’opérations supplémentaires, suivies d’une autre commande “end transaction” implicite / explicite, sont obsolètes. . Le monde des services Web s’est éloigné du modèle RPC il y a longtemps; RPC / encodé dans SOAP n’est même pas compatible WS-I!

    Au lieu de procédures , les services SOAP sont construits autour du concept de messages . Un seul message contient toutes les informations nécessaires pour effectuer une transaction complète. Si vous soumettez une commande, le message OrderRequest contiendra les informations sur le client, les informations de commande, les détails de la commande, les détails de paiement … tout ce que le serveur pourrait avoir besoin de savoir sur une seule commande.

    Nous avons des transactions WS qui définissent la sémantique des transactions dissortingbuées, mais elles ne sont pas vraiment destinées à prendre en charge la sémantique RPC-like du client, elles sont destinées aux orchestrations lorsque plusieurs services doivent participer à la même transaction. Par exemple, votre service de commande doit faire appel à un service de traitement des paiements pour valider les informations de carte de crédit et enregistrer un paiement, qui doit être annulé si le service de traitement constate que vous êtes en rupture de stock. avoir l’idée. Tout cela se passe dans l’environnement du serveur, donc rien ne vous empêche de faire la même chose dans REST.

    Dans REST, vous avez des ressources plutôt que des messages , mais le concept est très similaire. Au lieu d’un message OrderRequest , le client soumet ( PUT ) une ressource Order et la ressource doit contenir toutes les informations nécessaires pour terminer la transaction. Certes, si vous essayez d’effectuer des orchestrations complexes, vous pouvez trouver REST un peu lourd par rapport à SOAP, mais cela ne signifie pas que vous ne pouvez pas continuer à utiliser REST pour votre front-end , simplement que SOAP vous servira mieux pour vos services back-end .

    La réalité, cependant, est que 99% du temps, les gens n’ont pas besoin de la complexité des transactions WS. Je le sais parce que j’utilise SOAP (WCF) presque exclusivement et que j’utilise rarement WS-Transactions.

    Dans REST, “l’état” réside sur le client. Le serveur indique au client: “Voici toutes les informations dont vous avez besoin pour créer cette ressource (complétez cette transaction)”. Mais ce formulaire vierge ne commence pas réellement une transaction. Il appartient au client de fournir les informations – remplissez le formulaire, pour ainsi dire. Ce que le client fait pendant qu’il remplit le formulaire ne concerne pas le serveur; lorsque le client envoie enfin le formulaire fini au serveur, il est validé dans son intégralité. C’est similaire à une unité de travail, sauf que le client est celui qui garde la trace du “travail”.

    J’espère que cela donne une meilleure idée de la façon dont les transactions peuvent être et sont réalisées sur REST. Ils s’appuient simplement sur un concept de message / ressource plus riche et sur une forme de concurrence optimiste.

    Parce que tous les systèmes ne nécessitent pas de transactions.

    Je connais des systèmes de comptabilité en ligne (SaaS) très performants dotés d’une API non transactionnelle basée sur REST pour créer, récupérer et manipuler des factures, etc. Ils sont largement reconnus pour leur API et la facilité d’intégration de leur système avec d’autres parties. L’API est facile à entretenir, utilisable sur de nombreuses plates-formes et garantit une compatibilité ascendante relativement simple.

    Le manque de transactions peut être un véritable casse-tête, mais la plupart du temps, lorsque leurs serveurs ne sont pas trop chargés, l’API fonctionne très bien.

    Parfois, moins que parfait est juste assez bon.