Je suis en train de concevoir une API HTTP, je l'espère la rendre aussi RESTful que possible.
Il existe certaines actions dont la fonctionnalité est répartie sur quelques ressources et doit parfois être annulée.
Je me suis dit que cela ressemble à un modèle de commande, mais comment puis-je le modéliser en une ressource?
Je vais présenter une nouvelle ressource nommée XXAction, comme DepositAction, qui sera créée par quelque chose comme ça
POST /card/{card-id}/account/{account-id}/Deposit
AmountToDeposit=100, different parameters...
cela va en fait créer une nouvelle DepositAction et activer sa méthode Do / Execute. Dans ce cas, le retour d'un état HTTP 201 créé signifie que l'action a été exécutée avec succès.
Plus tard, si un client souhaite consulter les détails de l'action, il peut
GET /action/{action-id}
La mise à jour / PUT devrait être bloquée, je suppose, car elle n'est pas pertinente ici.
Et pour annuler l'action, j'ai pensé à utiliser
DELETE /action/{action-id}
qui appellera en fait la méthode Undo de l'objet concerné et changera son statut.
Disons que je suis content d'un seul Do-Undo, je n'ai pas besoin de refaire.
Cette approche est-elle correcte?
Y a-t-il des pièges, des raisons de ne pas l'utiliser?
Est-ce compris du POV des clients?
la source
Réponses:
Vous ajoutez une couche d'abstraction qui prête à confusion
Votre API démarre très propre et simple. Un HTTP POST crée une nouvelle ressource de dépôt avec les paramètres donnés. Ensuite, vous sortez des rails en introduisant l'idée d '"actions" qui sont un détail d'implémentation plutôt qu'une partie centrale de l'API.
Comme alternative, considérez cette conversation HTTP ...
Maintenant, vous voulez annuler cette opération (techniquement, cela ne devrait pas être autorisé dans un système comptable équilibré mais quoi de plus):
Le consommateur d'API sait qu'il s'agit d'une ressource de dépôt et est en mesure de déterminer quelles opérations sont autorisées sur celle-ci (généralement via OPTIONS dans HTTP).
Bien que la mise en œuvre de l'opération de suppression soit effectuée via des "actions" aujourd'hui, il n'y a aucune garantie que lorsque vous migrez ce système de, disons, C # vers Haskell et maintenez le front-end que le concept secondaire d'une "action" continuerait à ajouter de la valeur , alors que le concept principal de dépôt le fait certainement.
Modifier pour couvrir une alternative à DELETE et Deposit
Afin d'éviter une opération de suppression, mais toujours de supprimer efficacement le dépôt, vous devez procéder comme suit (en utilisant une transaction générique pour permettre le dépôt et le retrait):
Une nouvelle ressource Transaction est créée qui a exactement le montant opposé (-100). Cela a pour effet d'équilibrer le compte à 0, annulant la transaction d'origine.
Vous pourriez envisager de créer un point de terminaison "utilitaire" comme
pour obtenir le même effet. Cependant, cela rompt la sémantique d'un URI comme étant un identifiant en introduisant un verbe. Vous feriez mieux de vous en tenir aux noms dans les identificateurs et de limiter les opérations aux verbes HTTP. De cette façon, vous pouvez facilement créer un permalien à partir de l'identifiant et l'utiliser pour des GET et ainsi de suite.
la source
La principale raison de l'existence de REST est la résilience contre les erreurs de réseau. À quelle fin toutes les opérations doivent être idempotentes .
L'approche de base semble raisonnable, mais la façon dont vous décrivez la
DepositAction
création ne semble pas être idempotente, ce qui devrait être corrigé. En demandant au client de fournir un ID unique qui sera utilisé pour détecter les demandes en double. Donc, la création changerait pourSi un autre PUT vers la même URL est effectué avec le même contenu que précédemment, la réponse doit toujours être
201 created
si le contenu est le même et l'erreur si le contenu est différent. Cela permet au client de simplement retransmettre la demande en cas d'échec, car le client ne peut pas dire si la demande ou la réponse a été perdue.Il est plus logique d'utiliser PUT, car il écrit simplement la ressource et est idempotent, mais l'utilisation de POST ne poserait pas vraiment de problème non plus.
Pour consulter les détails de la transaction, le client aura
GET
la même URL, c.-à-d.et pour l'annuler, il peut le SUPPRIMER. Mais si cela a vraiment quelque chose à voir avec l'argent comme le suggère l'échantillon, je suggérerais de le mettre avec des drapeaux "annulés" ajoutés à la place pour la responsabilité (qu'il reste une trace de transaction créée et annulée).
Vous devez maintenant choisir une méthode de création de l'identifiant unique. Vous avez plusieurs options:
la source