Le contexte
En raison de l'apatridie du style architectural REST, chaque demande est complètement isolée, ce qui conduit le serveur à ne jamais stocker d'informations sur le client.
Ainsi, le contrôle d'accès concurrentiel pessimiste ne convient pas car il nécessiterait que le magasin de serveurs dont le client obtient le verrou sur une ressource. Un contrôle de concurrence optimiste est ensuite utilisé, à l'aide de l'en- Etag
tête. (btw, comme je l'ai demandé là /programming/30080634/concurrency-in-a-rest-api )
Problème
Le principal problème avec un mécanisme de contrôle de concurrence optimiste est que vous autorisez tout le temps, tous les clients, à effectuer toutes les opérations.
Et j'aimerais éviter cela sans enfreindre le principe de l'apatridie de REST. Je veux dire que tous les clients ne peuvent effectuer aucune opération à tout moment.
Question
Dans mon esprit, cela serait possible avec un mécanisme de contrôle d'accès concurrentiel semi-optimiste , comme celui-ci:
- Les clients peuvent demander un jeton
- Un seul jeton peut être généré et a une durée de validité limitée
- Pour effectuer des opérations sur les ressources (telles que POST ou PUT ), le client doit donner ce jeton dans le corps (ou en-tête?) De la demande. Le client qui n'a pas le jeton ne peut pas effectuer ces opérations.
Il est très similaire au contrôle de concurrence optimiste, sauf qu'un seul client peut effectuer certaines opérations (celui qui a obtenu le jeton) ... à l'opposé de "tous les clients peuvent effectuer toutes les opérations".
Ce mécanisme est-il compatible avec un style architectural REST? Brise-t-il une de ses contraintes? Je pensais poser des questions sur SO, mais cela semble plutôt une question de haut niveau, liée à la conception de logiciels.
la source
Transaction
explicitement une ressource.Etag
? AvecEtag
vous n'êtes jamais sûr que vos opérations seront terminées, vous pourriez avoir une situation où vous n'effectuerez jamais aucune opération. Avec une serrure, vous êtes sûr au moins d'effectuer votre opération. Donc, avoir un simple verrou est juste un milieu entre un environnement où des "conflits élevés" et des "conflits rares" peuvent se produire.Réponses:
Vous ne devez jamais (comme jamais jamais) verrouiller une ressource en attendant une interaction utilisateur.
À un moment donné, certains de vos utilisateurs décolleront pour un long week-end, laissant certains enregistrements vitaux verrouillés.
Ah mais vous ne laisserez pas cela se produire parce que vous avez un schéma intelligent de résolution de time out / deadlock; puis à un moment donné, cela ira horriblement mal et un utilisateur qui a reçu un joli message "votre widget a été commandé" criera au service d'assistance pour savoir pourquoi son widget n'a pas été livré.
La plupart des gens peuvent gérer le message "Désolé, un autre utilisateur vient de commander cette pièce".
la source
L'utilisation de jetons est très courante dans les API, ces jetons sont généralement envoyés en tant qu'en-tête et ont un cycle de vie clair. Pensez par exemple à OAuth.
Quel que soit votre langage de programmation ou votre infrastructure, les API REST sont similaires.
Je peux penser à plusieurs scénarios où vous souhaitez limiter la concurrence, deux d'entre eux sont:
Plusieurs clients mettant à jour les mêmes ressources comme une ligne de base de données. Par exemple: deux demandes simultanées, l'une supprime un enregistrement et l'autre essaie de mettre à jour le même enregistrement. En fonction de votre base de données et de la façon dont vous l'avez configurée, vous pouvez obtenir un verrou sur les enregistrements ou une opération non valide car les données seront différentes ou n'existeront pas.
Un super utilisateur ou administrateur effectuant des actions spéciales avec l'API.
Que faire dans ces cas?
Utilisez des transactions dans la base de données, des singletons, des verrous et des mécanismes similaires pour synchroniser l'accès aux ressources.
Le jeton pourrait fonctionner, je pense que ce sera mieux si vous ne stockez pas d'informations sur le client, juste sur le jeton lui-même. En une seule étape, vous pouvez valider l'utilisateur et attribuer le jeton. Ensuite, validez simplement que le jeton est vivant et qu'il est valide. Utilisez un jeton qui peut être déchiffré pour obtenir des informations supplémentaires. Vous pouvez stocker s'il s'agit d'un jeton spécial et ne l'autoriser qu'à la fois. De cette façon, vous validez le jeton, pas l'utilisateur.
J'espère que ça aide.
la source
REST seul est vraiment trop primitif, vraiment. Vous pouvez commencer avec REST, mais à terme, votre application riche aura besoin de requêtes avec jointures et de mises à jour avec transactions. Chaque développeur tentant d'ajouter ces éléments par lui-même serait sujet aux erreurs et incohérent. Heureusement, il existe une nouvelle norme appelée OData qui fait exactement cela. Il se superpose à REST et fournit (1) un langage de requête qui permet des jointures simples en utilisant des propriétés de navigation (sans avoir à exposer des clés étrangères), et, (2) un traitement par lots qui inclut des ensembles de modifications atomiques.
Voir ici pour (1) https://stackoverflow.com/a/3921423/471129 , et,
Voir ici et pour (2) https://stackoverflow.com/a/21939972/471129
la source