J'ai une page Web au format assistant. Le bouton de soumission à l'API sera à la 4ème étape de l'assistant. Cependant, je souhaite que les données saisies soient stockées dans la base de données avant de passer à l'étape suivante de l'assistant. Je veux également que l'API REST fonctionne pour les pages ayant un seul onglet.
J'ai donc conçu l'API pour prendre une action de paramètre de requête = brouillon ou soumettre. Si l'action est provisoire, seuls certains champs sont obligatoires. Si une action est soumise, tous les champs sont obligatoires. Les validations dans la couche de service de l'API REST seront effectuées en fonction du paramètre de requête. On dirait que je dois spécifier explicitement les clauses if / else dans la documentation. Est-ce une forme acceptable de conception RESTful? Quelle serait la meilleure conception avec ces exigences?
Réponses:
Puisque vous souhaitez conserver des éléments sur le serveur entre les étapes de l'assistant, il semble parfaitement acceptable de considérer chaque étape comme une ressource distincte. Quelque chose dans ce sens:
En incluant des liens hypermédias dans la réponse, vous pouvez informer le client de ce qu'il peut faire après cette étape - avancer ou reculer pour les étapes intermédiaires, et rien pour l'étape finale. Vous pouvez en voir un exemple dans la figure 5 ici .
la source
in_progress
oudraft
.J'avais dû faire quelque chose de similaire il y a quelque temps, et ce qui suit décrit ce que nous nous retrouvons.
Nous avons deux tables, Item et UnfinishedItem. Lorsque l'utilisateur remplit les données avec l'assistant, les données sont stockées dans la table UnfinishedItem. A chaque étape de l'assistant, le serveur valide les données saisies lors de cette étape. Lorsque l'utilisateur a terminé avec l'Assistant, l'Assistant affiche un formulaire masqué / en lecture seule dans une page de confirmation qui affiche toutes les données à soumettre. L'utilisateur peut consulter cette page et revenir à l'étape appropriée pour corriger les erreurs. Une fois que l'utilisateur est satisfait de ses entrées, l'utilisateur clique sur Soumettre et l'assistant soumet ensuite toutes les données des champs de formulaire masqué / en lecture seule au serveur API. Lorsque le serveur API traite cette demande, il réexécute toutes les validations qu'il a effectuées à chaque étape de l'assistant et effectue des validations supplémentaires qui ne correspondent pas aux étapes individuelles (par exemple, les validations globales, les validations coûteuses).
Les avantages de l'approche à deux tables:
dans la base de données, vous pouvez avoir des contraintes plus strictes sur la table Item que sur la table UnfinishedItem; vous n'avez pas besoin d'avoir des colonnes facultatives qui seront réellement requises lorsque l'assistant aura terminé.
Les requêtes agrégées sur les éléments finis pour les rapports sont plus faciles car vous n'avez pas à vous rappeler d'exclure les éléments inachevés. Dans notre cas, nous n'avons jamais eu besoin de faire des requêtes agrégées entre Item et UnfinishedItems, donc ce n'est pas un problème.
Le désavantage:
J'ai envisagé d'autres possibilités et pourquoi nous ne les avons pas choisies:
la source
if
déclarations vérifiant l'état du brouillon tout au long de vos validations, ce qui ne serait tout simplement pas bon. Bien que certains cadres très sophistiqués comme Ruby on Rails puissent considérablement simplifier ce problème s'ils sont correctement mis en œuvre.J'ai implémenté cela d'une manière similaire à un mélange de solutions @ guillauma31 et @Lie Ryan.
Voici les concepts clés:
/users/:id_user/profile/step_1
,.../step_2
, etc.).../profile/confirm
. Cette ressource n'a pas besoin de recevoir à nouveau toutes les données. Il marque uniquement les données comme correctes et complètes.Les gars du front-end doivent prendre soin des jetons pour que le flux de va-et-vient de l'assistant fonctionne.
L'API est sans état et atomique.
Pour faire fonctionner un "assistant en une étape" avec cette configuration, vous devez modifier certaines choses, comme supprimer le flux de jetons ou créer une ressource pour renvoyer des jetons en fonction du type d'assistant ou même créer une nouvelle ressource uniquement pour remplir ce single spécifique assistant étape (comme
PUT /users/:id_user/profile/
).la source