Ich habe eine Webseite im Assistentenformat. Die Übermittlungsschaltfläche an die API befindet sich im 4. Schritt des Assistenten. Ich möchte jedoch, dass die eingegebenen Daten in der Datenbank gespeichert werden, bevor Sie mit dem nächsten Schritt im Assistenten fortfahren. Ich möchte auch, dass die REST-API für die Seiten mit einer einzelnen Registerkarte funktioniert.
Daher habe ich die API so konzipiert, dass sie einen Abfrageparameter action = Draft oder Submit ausführt. Wenn es sich um eine Entwurfsaktion handelt, sind nur bestimmte Felder obligatorisch. Wenn die Aktion gesendet wird, sind alle Felder obligatorisch. Validierungen in der Service-Schicht der REST-API werden basierend auf dem Abfrageparameter durchgeführt. Es sieht so aus, als müsste ich die if / else-Klauseln in der Dokumentation explizit angeben. Ist dies eine akzeptable Form von RESTful Design? Was wäre das beste Design mit diesen Anforderungen?
Antworten:
Da Sie die Dinge zwischen den Assistentenschritten auf dem Server beibehalten möchten, ist es durchaus akzeptabel, jeden Schritt als separate Ressource zu betrachten. Etwas in diese Richtung:
Indem Sie Hypermedia-Links in die Antwort aufnehmen, können Sie den Client darüber informieren, was er nach diesem Schritt tun kann - gehen Sie für Zwischenschritte vorwärts oder rückwärts und für den letzten Schritt nichts. Ein Beispiel dafür sehen Sie in Abbildung 5 hier .
quelle
in_progress
oderdraft
.Ich musste vor einiger Zeit etwas Ähnliches tun, und das Folgende beschreibt, was wir am Ende haben.
Wir haben zwei Tabellen, Item und UnfinishedItem. Wenn der Benutzer die Daten mit dem Assistenten ausfüllt, werden die Daten in der Tabelle UnfinishedItem gespeichert. Bei jedem Assistentenschritt überprüft der Server die während dieses Schritts eingegebenen Daten. Wenn der Benutzer mit dem Assistenten fertig ist, rendert der Assistent ein verstecktes / schreibgeschütztes Formular auf einer Bestätigungsseite, auf der alle zu übermittelnden Daten angezeigt werden. Der Benutzer kann diese Seite überprüfen und zum entsprechenden Schritt zurückkehren, um Fehler zu beheben. Sobald der Benutzer mit seinen Eingaben zufrieden ist, klickt er auf Senden und der Assistent sendet alle Daten in den ausgeblendeten / schreibgeschützten Formularfeldern an den API-Server. Wenn der API-Server diese Anforderung verarbeitet, führt er alle Überprüfungen erneut aus, die er in jedem Schritt des Assistenten durchgeführt hat, und führt zusätzliche Überprüfungen durch, die nicht in die einzelnen Schritte passen (z. B. globale Überprüfungen, teure Überprüfungen).
Die Vorteile des Zwei-Tabellen-Ansatzes:
In der Datenbank können strengere Einschränkungen für die Item-Tabelle gelten als für die UnfinishedItem-Tabelle. Sie müssen keine optionalen Spalten haben, die nach Abschluss des Assistenten tatsächlich erforderlich sind.
Aggregierte Abfragen über die fertigen Elemente für die Berichterstellung sind einfacher, da Sie nicht daran denken müssen, die unfertigen Elemente auszuschließen. In unserem Fall mussten wir nie aggregierte Abfragen zwischen Item und UnfinishedItems durchführen, daher ist dies kein Problem.
Der Nachteil:
Andere Möglichkeiten, die ich in Betracht gezogen habe und warum wir nicht mit ihnen gegangen sind:
quelle
if
Aussagen, die während Ihrer gesamten Validierung auf den Entwurfsstatus prüfen, was einfach nicht gut wäre. Obwohl einige sehr ausgefeilte Frameworks wie Ruby on Rails dieses Problem bei korrekter Implementierung erheblich vereinfachen könnten.Ich habe dies auf ähnliche Weise implementiert wie eine Mischung aus @ guillauma31 und @Lie Ryans Lösungen.
Hier sind die Schlüsselkonzepte:
/users/:id_user/profile/step_1
,.../step_2
etc.).../profile/confirm
. Diese Ressource muss nicht alle Daten erneut empfangen. Es markiert nur die Daten als korrekt und vollständig.Die Front-End-Leute müssen sich um die Token kümmern, damit der Hin- und Herfluss des Assistenten funktioniert.
Die API ist zustandslos und atomar.
Damit ein "Ein-Schritt-Assistent" mit diesem Setup funktioniert, müssen Sie einige Dinge ändern, z. B. den Token-Fluss entfernen oder eine Ressource erstellen, um Token basierend auf dem Assistententyp zurückzugeben, oder sogar eine neue Ressource erstellen, um nur diese bestimmte Single zu füllen Schritt-Assistent (wie
PUT /users/:id_user/profile/
).quelle