Ich habe Probleme zu bestimmen, wie erholsame URLs entworfen werden sollen. Ich bin alle für den erholsamen Ansatz, URLs mit Substantiven und nicht mit Verben zu verwenden, verstehe nicht, wie das geht.
Wir erstellen einen Service zur Implementierung eines Finanzrechners. Der Rechner verwendet eine Reihe von Parametern, die wir über eine CSV-Datei hochladen. Die Anwendungsfälle würden Folgendes umfassen:
- Laden Sie neue Parameter hoch
- Holen Sie sich die neuesten Parameter
- Parameter für ein bestimmtes Geschäftsdatum abrufen
- Aktivieren Sie eine Reihe von Parametern
- Überprüfen Sie eine Reihe von Parametern
Ich denke, der erholsame Ansatz wäre, die folgenden Typ-URLs zu haben:
/parameters
/parameters/12-23-2009
Sie können die ersten drei Anwendungsfälle erreichen mit:
- POST, in dem Sie die Parameterdatei in die Post-Anfrage aufnehmen
- Erste URL abrufen
- Holen Sie sich die zweite URL
Aber wie macht man den 4. und 5. Anwendungsfall ohne Verb? Benötigen Sie keine URLs wie:
/parameters/ID/activate
/parameters/ID/validate
??
rest
restful-url
Marcus Leon
quelle
quelle
Antworten:
Vielleicht so etwas wie:
quelle
POST
ist in Ordnung, wenn Sie eine "Prozedur" ausführen müssen, z. B. die Parameter jedes Mal überprüfen, wenn Sie eine Anfrage senden. Wenn Sie jedoch den (Anwendungs-) Status der Ressource ändern, aktualisieren Sie tatsächlich die vorhandene Ressource, erstellen keine neue Ressource und stellen keine Verarbeitungsanforderung.POST
vsPUT
ist nicht genau wieinsert
vsupdate
.PUT
Aktualisiert die dem angegebenen Pfad entsprechende Ressource oder erstellt eine neue Ressource, die dem angegebenen Pfad entspricht.POST
erstellt irgendwo eine neue Ressource. Zum BeispielPUT /blog/posts/3/comments/5
wird den entsprechenden Kommentar aktualisieren, währendPOST /blog/posts/3/comments
eine neue erstellencomment
Ressource (und soll den Weg auf die neue Ressource in der Antwort zurück).PUT
idempotent ist, während diesPOST
nicht der Fall ist. Normalerweise sollten Sie Ihre Ergebnisse so stark wie möglich einschränken. Das Festhalten anPUT
hält dem Kunden des Dienstes weitere Informationen.Allgemeine Grundsätze für ein gutes URI-Design:
/resource
oder/resource/
; Erstellen Sie 301 Weiterleitungen von der, die Sie nicht verwenden(Hinweis: Ich habe nicht "RESTful URI Design" gesagt. URIs sind in REST im Wesentlichen undurchsichtig.)
Allgemeine Grundsätze für die Auswahl der HTTP-Methode:
Allgemeine Prinzipien des Webdienstdesigns mit HTTP:
201 Created
nach dem Erstellen einer Ressource; Die Ressource muss zum Zeitpunkt des Sendens der Antwort vorhanden sein202 Accepted
nachdem Sie eine Operation erfolgreich ausgeführt oder eine Ressource asynchron erstellt haben400 Bad Request
wenn jemand eine Operation an Daten ausführt, die eindeutig falsch sind; Für Ihre Anwendung kann dies ein Validierungsfehler sein. Im Allgemeinen reservieren Sie 500 für nicht erfasste Ausnahmen401 Unauthorized
wenn jemand auf Ihre API zugreift, ohne einen erforderlichenAuthorization
Header anzugeben, oder wenn die Anmeldeinformationen in derAuthorization
ungültig sind; Verwenden Sie diesen Antwortcode nicht, wenn Sie keine Anmeldeinformationen über einenAuthorization
Header erwarten .403 Forbidden
wenn jemand auf böswillige Weise auf Ihre API zugreift oder wenn er nicht autorisiert ist405 Method Not Allowed
wenn jemand POST verwendet, wenn er PUT usw. hätte verwenden sollen413 Request Entity Too Large
wenn jemand versucht, Ihnen eine unannehmbar große Datei zu senden418 I'm a teapot
beim Versuch, Kaffee mit einer Teekanne zu kochenETag
Header sind gut, wenn Sie eine Ressource leicht auf einen Hashwert reduzieren könnenLast-Modified
sollte Ihnen darauf hinweisen, dass es eine gute Idee ist, einen Zeitstempel für die Aktualisierung der Ressourcen einzuhaltenCache-Control
undExpires
sollte vernünftige Werte gegeben werdenIf-None-Modified
,If-Modified-Since
)In Bezug auf Ihre spezifische Frage sollte POST für Nr. 4 und Nr. 5 verwendet werden. Diese Operationen fallen unter die oben genannte "RPC-ähnliche" Richtlinie. Denken Sie für # 5 daran, dass POST nicht unbedingt verwendet werden muss
Content-Type: application/x-www-form-urlencoded
. Dies kann genauso gut eine JSON- oder CSV-Nutzlast sein.quelle
Wann immer es so aussieht, als ob Sie ein neues Verb benötigen, denken Sie daran, dieses Verb stattdessen in ein Substantiv umzuwandeln. Verwandeln Sie beispielsweise "Aktivieren" in "Aktivierung" und "Validieren" in "Validierung".
Aber nur von dem, was Sie geschrieben haben, würde ich sagen, dass Ihre Bewerbung viel größere Probleme hat.
Jedes Mal, wenn eine Ressource namens "Parameter" vorgeschlagen wird, sollte sie in den Gedanken jedes Projektteammitglieds rote Fahnen setzen. 'Parameter' kann buchstäblich auf jede Ressource angewendet werden. es ist nicht spezifisch genug.
Was genau repräsentiert ein 'Parameter'? Wahrscheinlich eine Reihe verschiedener Dinge, für die jeweils eine eigene Ressource vorgesehen sein sollte.
Ein anderer Weg, um dies zu erreichen: Wenn Sie Ihre Anwendung mit Endbenutzern besprechen (diejenigen, die vermutlich wenig über Programmierung wissen), welche Wörter verwenden sie selbst wiederholt?
Mit diesen Worten sollten Sie Ihre Anwendung gestalten.
Wenn Sie diese Konvertierung noch nicht mit potenziellen Benutzern durchgeführt haben, stoppen Sie jetzt alles und schreiben Sie erst dann eine weitere Codezeile! Nur dann hat Ihr Team eine Vorstellung davon, was gebaut werden muss.
Ich weiß nichts über Finanzsoftware, aber wenn ich raten müsste, würde ich sagen, dass einige der Ressourcen unter Namen wie "Bericht", "Zahlung", "Überweisung" und "Währung" geführt werden könnten.
Es gibt eine Reihe guter Bücher zu diesem Teil des Software-Design-Prozesses. Zwei, die ich empfehlen kann, sind domänengesteuerte Entwurfs- und Analysemuster .
quelle
Das Design Ihrer URLs hat nichts damit zu tun, ob Ihre Anwendung RESTful ist oder nicht. Der Ausdruck "RESTful URLs" ist daher Unsinn.
Ich denke, Sie sollten noch etwas darüber lesen, was REST eigentlich ist. REST behandelt die URLs als undurchsichtig und weiß daher nicht, was darin enthalten ist, ob es Verben oder Substantive gibt oder was auch immer. Möglicherweise möchten Sie Ihre URLs weiterhin entwerfen, aber es geht um die Benutzeroberfläche, nicht um REST.
Kommen wir jedoch zu Ihrer Frage: Die letzten beiden Fälle sind nicht RESTful und passen nicht in ein erholsames Schema. Das könnte man RPC nennen. Wenn Sie REST ernst nehmen, müssen Sie die Funktionsweise Ihrer Anwendung von Grund auf überdenken. Entweder das oder geben Sie REST auf und machen Sie Ihre App einfach als RPC-App.
Hrmmm vielleicht nicht.
Die Idee hier ist, dass Sie alles als Ressource behandeln müssen. Sobald ein Parametersatz eine URL hat, auf die Sie verweisen können, fügen Sie einfach Folgendes hinzu:
Aber auch dieses Aktivierungsobjekt ist RPC, nicht REST.
quelle
Die Aktivierungs- und Validierungsanforderungen sind Situationen, in denen Sie versuchen, den Status einer Ressource zu ändern. Es ist nicht anders, als eine Bestellung "abgeschlossen" oder eine andere Anfrage "eingereicht" zu machen. Es gibt zahlreiche Möglichkeiten, diese Art von Statusänderungen zu modellieren, aber eine, die meiner Meinung nach häufig funktioniert, besteht darin, Sammlungsressourcen für Ressourcen desselben Status zu erstellen und die Ressource dann zwischen den Sammlungen zu verschieben, um den Status zu beeinflussen.
zB Erstellen Sie einige Ressourcen wie,
Wenn Sie eine Reihe von Parametern aktivieren möchten, fügen Sie diese der ActiveParameters-Auflistung hinzu. Sie können den Parametersatz entweder als Entitätskörper übergeben oder eine URL als Abfrageparameter wie folgt übergeben:
Dasselbe kann mit den / ValidatedParameters gemacht werden. Wenn die Parameter nicht gültig sind, kann der Server "Bad Request" an die Anforderung zurückgeben, um die Parameter zur Sammlung validierter Parameter hinzuzufügen.
quelle
Ich würde die folgenden Meta-Ressourcen und Methoden vorschlagen.
Aktivieren Sie Parameter und / oder validieren Sie sie:
Überprüfen Sie, ob die Parameter aktiv und gültig sind:
quelle
Ich bin ein bisschen traurig zu sehen, dass es nach mehr als 10 Jahren keine Antwort gibt, die wirklich besagt, wie so etwas wie das im OP angeforderte in einer REST-Architektur entworfen werden könnte, daher habe ich das Bedürfnis, dies jetzt zu tun.
Das Wichtigste zuerst, was ist REST?! Das Akronym REST oder ReST steht für "Representational State Transfer" und definiert den Austausch des Zustands einer Ressource in einem bestimmten Repräsentationsformat. Das Darstellungsformat richtet sich nach dem ausgehandelten Medientyp. Im Fall des
application/html
Darstellungsformats kann es sich um einen Stream von HTML-formatiertem Textinhalt handeln, der im Browser gerendert wird, wahrscheinlich nachdem einige Stylesheet-Formatierungen angewendet wurden, um bestimmte Elemente an bestimmten Stellen zu positionieren.REST ist im Prinzip eine Verallgemeinerung des durchsuchbaren Webs, das wir alle kennen, obwohl es auf alle Arten von Anwendungen und nicht nur auf Browser abzielt. Daher gelten dieselben Konzepte, die für das Web gelten, auch für eine REST-Architektur. Eine Frage wie das Erreichen von "RESTful" -Ergebnissen besteht darin, die Frage zu beantworten, wie auf einer Webseite etwas erreicht werden kann, und dann dieselben Konzepte auf die Anwendungsebene anzuwenden.
Ein webbasierter Taschenrechner beginnt normalerweise mit einer "Seite", auf der Sie einige zu berechnende Werte eingeben können, bevor Sie die eingegebenen Daten an den Server senden. In HTML wird dies normalerweise über HTML-
<form>
Elemente erreicht, die einem Client die verfügbaren Parameter zum Festlegen, den Zielspeicherort zum Senden der Anforderung sowie das beim Senden der Eingabedaten anzuwendende Darstellungsformat beibringen. Dies kann dh so aussehen:Das obige Beispiel besagt, dass es zwei Eingabefelder gibt, die entweder vom Benutzer oder von anderen Automaten ausgefüllt werden können, und dass der Browser beim Aufrufen des Submit-Eingabeelements dafür sorgt, dass die Eingabedaten in a formatiert werden
application/x-www-form-urlencoded
gesendetes Darstellungsformat formatiert werdenPOST
in diesem Fall über die angegebene HTTP-Anforderungsmethode an den genannten Zielort . Wenn wir1
in dasfirstNumber
Eingabefeld und2
in dassecondNumber
Eingabefeld eingeben , generiert der Browser eine DarstellungfirstNumber=1&secondNumber=2
und sendet diese als Hauptnutzlast der tatsächlichen Anforderung an die Zielressource.Die an den Server gesendete HTTP-Rohanforderung kann daher folgendermaßen aussehen:
Der Server kann die Berechnung durchführen und mit einer weiteren HTML-Seite antworten, die das Ergebnis der Berechnung enthält, da die Anforderung anzeigt, dass der Client dieses Format versteht.
Wie Breton bereits betont hat, gibt es keine "RESTful" -URL oder URI. Eine URI / URL ist eine eigene Sache und sollte einem Client / Benutzer keine Bedeutung vermitteln. In dem obigen Rechnerbeispiel ist ein Benutzer einfach nicht daran interessiert, wohin er die Daten senden soll. Er ist nur daran interessiert, dass beim Auslösen des Übermittlungs-Eingabefelds die Anforderung gesendet wird. Alle zur Ausführung der Aufgabe erforderlichen Informationen sollten bereits vom Server bereitgestellt werden.
Ein Browser weiß möglicherweise auch nicht, dass die Anforderung tatsächlich einen Taschenrechner mit einigen Eingabeparametern versorgt. Es kann sich auch um eine Art Bestellformular handeln, das nur die nächste Formulardarstellung zurückgibt, um den Bestellvorgang fortzusetzen, oder um eine völlig andere Art von Ressource. Es führt einfach das aus, was die HTML-Spezifikation in einem solchen Fall verlangt, und es ist egal, was der Server tatsächlich tut. Dieses Konzept ermöglicht es einem Browser, dasselbe Darstellungsformat zu verwenden, um alle möglichen Dinge zu erledigen, z. B. einige Dinge in Ihrem bevorzugten Online-Shop zu bestellen, mit Ihren besten Freunden zu chatten, sich in einem Online-Konto anzumelden und so weiter.
Die Erschwinglichkeit bestimmter Elemente, z. B. im Fall des Eingabefelds "Senden", das normalerweise als Schaltfläche gerendert wird, definiert, was Sie damit tun sollen. Im Falle einer Schaltfläche oder eines Links werden Sie grundsätzlich aufgefordert, darauf zu klicken. Andere Elemente können unterschiedliche Leistungen vermitteln. Ein solcher Vorteil kann auch über Link-Beziehungen ausgedrückt werden , z. B. mit
preload
kommentierten Links, die einem Kunden im Grunde mitteilen, dass er den Inhalt der verknüpften Ressource bereits im Hintergrund laden kann, da der Benutzer diesen Inhalt höchstwahrscheinlich als Nächstes abrufen wird. Solche Link-Beziehungen sollten natürlich standardisiert sein oder dem Erweiterungsmechanismus für Beziehungstypen folgen, wie er durch Web-Linking definiert ist .Dies sind die grundlegenden Konzepte, die im Web verwendet werden und die auch in einer REST-Architektur verwendet werden sollten. Laut "Onkel Bob" Robert C. Martin geht es bei einer Architektur um Absicht, und die Absicht hinter der REST-Architektur ist die Entkopplung von Clients von Servern, damit sich Server in Zukunft frei entwickeln können, ohne befürchten zu müssen, dass sie Clients beschädigen. Dies erfordert leider viel Disziplin, da es so einfach ist, Kopplungen einzuführen oder schnelle Lösungen hinzuzufügen, um die Arbeit zu erledigen und weiterzumachen. Wie Jim Webber in einer REST-Architektur hervorhob, sollten Sie als Dienstanbieter versuchen, ein Domänenanwendungsprotokoll zu entwerfen , das einem textbasierten Computerspiel der 70er Jahre ähnelt, das Clients bis zum Ende eines Prozesses durchlaufen.
Was viele sogenannte "REST" -APIs in der Realität leider tun, ist alles andere als das. Sie sehen den Austausch von hauptsächlich JSON-basierten Daten, die in einer API-spezifischen externen Dokumentation angegeben sind, die normalerweise im laufenden Betrieb nur schwer dynamisch zu integrieren ist. Das Format, wie eine Anforderung aussehen muss, ist ebenfalls in der externen Dokumentation fest codiert, was zu einer Vielzahl von Implementierungsinterpretationen von URIs führt codiert. Dies um vordefinierte Typen zurückzugebenanstatt ein allgemeines Darstellungsformat zu verwenden, das im Voraus ausgehandelt wird. Dies verhindert, dass sich Server ändern, da Clients jetzt ein bestimmtes Datenformat (Hinweis, kein Darstellungsformat!) Für vordefinierte URIs erwarten. Dieser benutzerdefinierte Datenformataustausch verhindert außerdem, dass Clients mit anderen APIs interagieren, da das "Datenformat" normalerweise für eine bestimmte API gilt. Wir kennen dieses Konzept aus der Vergangenheit aus RPC-Technologien wie Corba, RMI oder SOAP, die wir als irgendwie böse verurteilen, obwohl Peppol erneut darauf zurückgegriffen hat, indem er AS2 durch AS4 als Standardübertragungsprotokoll ersetzt hat.
In Bezug auf die tatsächlich gestellte Frage unterscheidet sich das Senden von Daten als CSV-Datei nicht von der Verwendung von
application/x-www-form-urlencoded
Darstellungen oder ähnlichem. Jim Webber machte deutlich, dass HTTP schließlich nur ein Transportprotokoll ist, dessen Anwendungsdomäne die Übertragung von Dokumenten über das Web ist . Client und Server sollten mindestens beide unterstützen,text/csv
wie in RFC 7111 definiert . Diese CSV-Datei kann als Folge der Verarbeitung eines Medientyps generiert werden, der Formularelemente, ein Zielelement oder Attribut zum Senden der Anforderung sowie die HTTP-Methode zum Hochladen der Konfiguration definiert.Es gibt einige Medientypen, die Formulare wie HTML , HAL Forms , Halform , Ion oder Hydra unterstützen . Derzeit ist mir jedoch kein Medientyp bekannt, der die Eingabedaten automatisch
text/csv
direkt codieren kann. Daher muss möglicherweise ein Medientyp definiert und in der Medientypregistrierung von IANA registriert werden .Das Hoch- und Herunterladen des gesamten Parametersatzes sollte wohl kein Problem sein. Wie bereits erwähnt, ist der Ziel-URI nicht relevant, da ein Client den URI nur zum Abrufen neuer zu verarbeitender Inhalte verwendet. Das Filtern nach Geschäftsdatum sollte auch nicht zu schwierig sein. Hier sollte der Server jedoch dem Client alle Möglichkeiten bieten, aus denen der Client einfach wählen kann. In den letzten Jahren haben sich GraphQL und RestQL weiterentwickelt, die eine SQL-ähnliche Sprache einführen, die auf einen bestimmten Endpunkt ausgerichtet werden kann, um eine gefilterte Antwort zu erhalten. Im wahrsten Sinne des Wortes verstößt dies jedoch gegen die Idee hinter REST, da a) GraphQL nur einen einzigen Endpunkt verwendet, der die optimale Nutzung des Caching irgendwie verhindert, und b) die Kenntnis der verfügbaren Felder im Voraus erfordert, was zur Einführung einer Kopplung von Clients führen kann zum Basisdatenmodell der Ressource.
Das Aktivieren oder Deaktivieren bestimmter Konfigurationsparameter ist lediglich eine Frage des Auslösens der Hypermedia-Steuerelemente, die diesen Vorteil bieten. In HTML-Formularen kann dies ein einfaches Kontrollkästchen oder eine mehrzeilige Auswahl in einer Liste oder dergleichen sein. Abhängig vom Formular und der von ihm definierten Methode kann es dann möglicherweise die gesamte Konfiguration über senden
PUT
oder über die vorgenommenen Änderungen klug sein und nur eine teilweise Aktualisierung über durchführenPATCH
. Letzteres erfordert grundsätzlich eine Berechnung der Änderungsdarstellung auf die aktualisierte und speist den Server mit den erforderlichen Schritten, um die aktuelle Darstellung in die gewünschte umzuwandeln. Gemäß der PATH-Spezifikation muss dies innerhalb einer Transaktion erfolgen, damit entweder alle oder keine der Schritte angewendet werden.HTTP ermöglicht und ermutigt einen Server, eine empfangene Anfrage im Voraus zu validieren, bevor die Änderungen übernommen werden. Für PUT heißt es in der Spezifikation:
Um diesen Beitrag zusammenzufassen, sollten Sie entweder einen vorhandenen Medientyp verwenden, mit dem Sie einem Client die erforderlichen oder unterstützten Eingabeparameter, den Zielspeicherort für die Anforderung, den zu verwendenden Vorgang sowie den Medientyp beibringen können Die Anfrage muss formatiert sein oder Sie müssen eine eigene Anfrage definieren, die Sie bei IANA registrieren. Letzteres kann erforderlich sein, wenn Sie die Eingabe in konvertieren möchten
text/csv
Laden Sie anschließend die CSV-Darstellung auf den Server hoch. Die Validierung sollte erfolgen, bevor die Änderungen auf die Ressource angewendet werden. Die tatsächliche URI sollte für andere Clients nur relevant sein, um zu bestimmen, wohin die Anfrage gesendet werden soll, und kann daher von Ihnen, dem Service-Implementierer, frei gewählt werden. Wenn Sie diese Schritte ausführen, haben Sie so gut wie die Freiheit, Ihre Serverseite jederzeit zu ändern, und Clients werden nicht beschädigt, wenn sie die verwendeten Medientypen unterstützen.quelle
Bearbeiten: In der Tat hätte die URI verhindert
GET
, dass Anforderungen idempotent bleiben.Für die Validierung würde jedoch die Verwendung von HTTP-Statuscodes zur Benachrichtigung über die Gültigkeit einer Anforderung (zum Erstellen eines neuen oder zum Ändern eines vorhandenen 'Parameters') zu einem Restful-Modell passen.
Melden Sie sich mit einem
400 Bad Request
Statuscode zurück, wenn die übermittelten Daten ungültig sind / sind und die Anforderung vor der erneuten Übermittlung geändert werden muss ( HTTP / 1.1-Statuscodes ).Dies hängt jedoch davon ab, dass die Validierung zum Zeitpunkt der Einreichung erfolgt, anstatt sie wie in Ihrem Anwendungsfall zu verschieben. Die anderen Antworten haben geeignete Lösungen für dieses Szenario.
quelle
In einer REST-Umgebung ist jede URL eine eindeutige Ressource. Was sind Ihre Ressourcen? Ein Finanzrechner hat wirklich keine offensichtlichen Ressourcen. Sie müssen sich mit den von Ihnen aufgerufenen Parametern befassen und die Ressourcen abrufen. Beispielsweise kann ein Tilgungskalender für ein Darlehen eine Ressource sein. Die URL für den Kalender kann Startdatum, Laufzeit (in Monaten oder Jahren), Zeitraum (wenn die Zinsen zusammengesetzt werden), Zinssatz und Anfangsprinzip enthalten. Mit all diesen Werten haben Sie einen bestimmten Zahlungskalender:
Jetzt weiß ich nicht, was Sie berechnen, aber Ihr Konzept einer Parameterliste klingt nicht RESTful. Wie jemand anderes sagte, klingen Ihre oben genannten Anforderungen mehr nach XMLRPC. Wenn Sie nach REST suchen, benötigen Sie Substantive. Berechnungen sind keine Substantive, sondern Verben, die auf Substantive einwirken. Sie müssen es umdrehen, um die Substantive aus Ihren Berechnungen herauszuziehen.
quelle