Ich kämpfe darum, herauszufinden, wie man erholsame URLs erstellt. Ich bin alle für den erholsamen Ansatz, URLs mit Nomen und nicht mit Verben zu verwenden, und verstehe nicht, wie man das macht.
Wir schaffen einen Service, um einen Finanzrechner zu implementieren. Der Rechner verwendet eine Reihe von Parametern, die wir über eine CSV-Datei hochladen. Die Anwendungsfälle umfassen:
Ich gehe davon aus, dass die folgenden URL-Typen hilfreich sind:
/parameters
/parameters/12-23-2009
Sie können die ersten drei Anwendungsfälle erreichen mit:
Aber wie macht man den 4. und 5. Anwendungsfall ohne Verb? Würdest du keine URLs brauchen wie:
/parameters/ID/activate
/parameters/ID/validate
??
Vielleicht so etwas wie:
PUT /parameters/activation HTTP/1.1
Content-Type: application/json; encoding=UTF-8
Content-Length: 18
{ "active": true }
Allgemeine Grundsätze für ein gutes URI-Design:
/resource
Oder /resource/
Bevorzugen; Erstellen Sie 301 Weiterleitungen von denen, 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 Web Service Designs mit HTTP:
201 Created
Nach dem Erstellen einer Ressource; resource muss zum Zeitpunkt des Absendens der Antwort vorhanden sein202 Accepted
Nach erfolgreicher Ausführung eines Vorgangs oder asynchroner Erstellung einer Ressource400 Bad Request
Wenn jemand eine Operation mit Daten ausführt, die eindeutig gefälscht sind; Für Ihre Anwendung könnte dies ein Validierungsfehler sein. In der Regel 500 für nicht abgefangene Ausnahmen reservieren401 Unauthorized
, Wenn jemand auf Ihre API zugreift, ohne einen erforderlichen Authorization
-Header anzugeben, oder wenn die Anmeldeinformationen in Authorization
ungültig sind; Verwenden Sie diesen Antwortcode nicht, wenn Sie keine Anmeldeinformationen über einen Authorization
-Header erwarten.403 Forbidden
, Wenn jemand auf eine Weise auf Ihre API zugreift, die böswillig sein könnte 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 unzulässig große Datei zu senden418 I'm a teapot
beim Kaffeebrühen mit einer TeekanneETag
-Header eignen sich gut, wenn Sie eine Ressource leicht auf einen Hash-Wert reduzieren könnenLast-Modified
Sollte Ihnen anzeigen, dass es eine gute Idee ist, den Zeitstempel der Ressourcenaktualisierung einzuhaltenCache-Control
Und Expires
sollten sinnvolle Werte erhaltenIf-None-Modified
, If-Modified-Since
)In Bezug auf Ihre spezielle Frage sollte POST für # 4 und # 5 verwendet werden. Diese Vorgänge fallen unter die oben genannte "RPC-ähnliche" Richtlinie. Denken Sie für # 5 daran, dass POST nicht unbedingt Content-Type: application/x-www-form-urlencoded
Verwenden muss. Dies kann genauso gut eine JSON- oder CSV-Nutzlast sein.
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 nach dem, was Sie geschrieben haben, würde ich sagen, dass Ihre Anwendung viel größere Probleme hat.
Jedes Mal, wenn eine Ressource namens "Parameter" vorgeschlagen wird, sollte sie in den Köpfen aller Projektteammitglieder 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 von verschiedenen Dingen, denen jeweils eine separate Ressource gewidmet sein sollte.
Ein anderer Weg, dies zu erreichen: Wenn Sie Ihre Anwendung mit Endbenutzern besprechen (die vermutlich wenig über Programmierung wissen), welche Wörter verwenden sie selbst wiederholt?
Das sind die Wörter, um die Sie Ihre Anwendung herum entwerfen sollten.
Wenn Sie diese Konvertierung noch nicht mit potenziellen Nutzern durchgeführt haben - stoppen Sie jetzt alles und schreiben Sie erst dann eine weitere Codezeile! Nur dann hat Ihr Team eine Vorstellung davon, was aufgebaut werden muss.
Ich weiß nichts über Finanzsoftware, aber wenn ich raten müsste, würde ich sagen, dass einige der Ressourcen mit Namen wie "Bericht", "Zahlung", "Überweisung" und "Währung" versehen sind.
Es gibt eine Reihe guter Bücher über diesen Teil des Software-Designprozesses. Zwei, die ich empfehlen kann, sind Domain Driven Design und Analysis Patterns .
Das Design Ihrer URLs hat nichts damit zu tun, ob Ihre Anwendung REST-fähig ist oder nicht. Der Ausdruck "RESTful URLs" ist daher Unsinn.
Ich denke, Sie sollten etwas mehr darüber lesen, was REST eigentlich ist. REST behandelt die URLs als undurchsichtig und weiß daher nicht, was in ihnen enthalten ist. ob es Verben oder Substantive gibt oder was auch immer. Vielleicht möchten Sie Ihre URLs immer noch entwerfen, aber es geht um die Benutzeroberfläche, nicht um REST.
Kommen wir jedoch zu Ihrer Frage: Die letzten beiden Fälle sind nicht REST-konform und passen nicht in ein ruhiges Schema. Das könnten Sie RPC nennen. Wenn Sie REST ernst meinen, müssen Sie die Funktionsweise Ihrer Anwendung von Grund auf überdenken. Entweder das oder REST und mache deine App einfach als RPC-App.
Hrmmm vielleicht nicht.
Die Idee dabei 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:
GET [parametersurl]/validationresults
POST [paramatersurl]
body: {command:"activate"}
Aber auch dieses aktivierende Ding ist RPC, nicht REST.
Die Aktivierungs- und Validierungsanforderungen sind Situationen, in denen Sie versuchen, den Status einer Ressource zu ändern. Es ist nicht anders, als wenn eine Bestellung "abgeschlossen" oder eine andere Anfrage "übermittelt" wird. Es gibt zahlreiche Möglichkeiten, diese Art der Zustandsänderung zu modellieren. Ich finde jedoch, dass dies häufig funktioniert, indem Sie Sammlungsressourcen für Ressourcen desselben Zustands erstellen und dann die Ressource zwischen den Sammlungen verschieben, um den Zustand zu beeinflussen.
z.B. Erstellen Sie einige Ressourcen wie
/ActiveParameters
/ValidatedParameters
Wenn Sie einen Parametersatz aktivieren möchten, fügen Sie diesen der ActiveParameters-Auflistung hinzu. Sie können den Parametersatz entweder als Entitätskörper oder wie folgt als Abfrageparameter eine URL übergeben:
POST /ActiveParameters?parameter=/Parameters/{Id}
Dasselbe kann mit den/ValidatedParameters durchgeführt 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.
Ich würde die folgenden Meta-Ressourcen und Methoden vorschlagen.
Parameter aktivieren und/oder validieren:
> PUT /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Content-Type: application/json
> Connection: close
>
> {'active': true, 'require-valid': true}
>
< HTTP/1.1 200 OK
< Connection: close
<
Überprüfen Sie, ob die Parameter aktiv und gültig sind:
> GET /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Connection: close
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: close
<
< {
< 'active': true,
< 'require-valid': true,
< 'valid': {'status': false, 'reason': '...'}
< }
<
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 Parametern befassen, die Sie aufrufen, und diese abrufen B. ein Tilgungskalender für ein Darlehen eine Ressource dar. Die URL für den Kalender kann Startdatum, Laufzeit (in Monaten oder Jahren), Zeitraum (bei Zinserhöhung), Zinssatz und Anfangsprinzip enthalten Mit all diesen Werten haben Sie einen bestimmten Zahlungskalender:
http://example.com/amort_cal/2009-10-20/30yrsfixed/monthly/5.00/200000
Jetzt weiß ich nicht, was Sie berechnen, aber Ihr Konzept einer Parameterliste klingt nicht RESTful. Wie schon jemand gesagt hat, klingen Ihre obigen Anforderungen eher 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 Kalkulationen zu ziehen.
Edit: In der Tat hätte der URI verhindert, dass GET
Anfragen idempotent blieben.
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 Ändern eines vorhandenen 'Parameters') zu einem Restful-Modell passen.
Melde dich mit einem 400 Bad Request
Statuscode, wenn die übermittelten Daten ungültig sind und die Anforderung vor der erneuten Übermittlung geändert werden muss ( HTTP/1.1 Statuscodes ).
Dies hängt jedoch von der Validierung zum Zeitpunkt der Einreichung ab, anstatt sie wie in Ihrem Anwendungsfall aufzuschieben. Die anderen Antworten haben passende Lösungen für dieses Szenario.