Nachgestellter Schrägstrich in der RESTful-API

60

Ich habe eine Debatte darüber geführt, was mit einem abschließenden Schrägstrich in einer RESTful-API geschehen soll.

Nehmen wir an, ich habe eine Ressource namens Hunde und untergeordnete Ressourcen für einzelne Hunde. Wir können daher Folgendes tun:

GET/PUT/POST/DELETE http://example.com/dogs
GET/PUT/POST/DELETE http://example.com/dogs/{id}

Aber was machen wir mit dem folgenden Sonderfall:

GET/PUT/POST/DELETE http://example.com/dogs/

Meine persönliche Meinung ist, dass dies bedeutet, eine Anfrage an eine einzelne Hunderessource mit id = zu senden null. Ich denke, dass die API eine 404 für diesen Fall zurückgeben sollte.

Andere sagen, die Anfrage greife auf die Hunderessource zu, dh der abschließende Schrägstrich wird ignoriert.

Kennt jemand die endgültige Antwort?

Gaz_Edge
quelle
2
Ich dachte, der RESTvolle Weg wäre, zwischen Hund / Ausweis und Hunden zu unterscheiden (dh alle Hunde).
pdr
Aus dem Buch RESTful Web Services - untergeordnete Ressourcen: Ressourcen, die in Bezug auf eine andere übergeordnete Ressource vorhanden sind, z. B. dogs / {id} Eine webfähige Datenbank kann eine Tabelle als Ressource und die einzelnen Datenbankzeilen als untergeordnete Ressourcen verfügbar machen .
Gaz_Edge
Wenn auf die Hunderessource zugegriffen wird, sollte der abschließende Schrägstrich ignoriert werden, was bedeutet, dass eine verbotene Antwort für den Versuch angezeigt wird, etwas zu löschen, auf das das Löschen nicht angewendet werden sollte. Ich denke, dass 404 auch akzeptabel ist. Ist es trotzdem wichtig?
Benjamin Gruenbaum
Ich folge nicht - wer hat gesagt, dass Sie keine Hunde löschen können? Wenn Sie Hunde löschen, werden sowohl sich selbst als auch alle einzelnen Hunde gelöscht. Deshalb halte ich es für riskant, Anrufe bei Hunden zuzulassen. Was ist, wenn der Kunde beabsichtigt, einen einzelnen Hund zu löschen, aber versehentlich die {ID} weggelassen hat? Das Ergebnis wäre, dass alle Hunde gelöscht würden. Es ist viel sicherer anzunehmen, dass er nach {id} null fragt und 404
Gaz_Edge
Ich würde dogsund dogs/als gleichwertig behandeln. Für mich ist klar, dass dogs/es sich um ein Verzeichnis handelt, das die einzelnen Hunde enthält. Es ist weniger klar, was es dogsist, aber ich würde es als gleichwertig behandeln, genau wie die meisten Webserver Zugriffe auf Verzeichnisse akzeptieren, ohne nachzulesen /.
CodesInChaos

Antworten:

50

Nichts davon ist maßgebend (da REST keine genaue Bedeutung hat). In der Originalarbeit zu REST gibt eine vollständige (nicht mit / endende) URL eine Ressource an, während eine mit einem Schrägstrich (/) endende Ressourcengruppe ist (wahrscheinlich nicht so formuliert).

Ein GET einer URL mit einem Schrägstrich am Ende soll die verfügbaren Ressourcen auflisten.

GET http://example.com/dogs/          /* List all the dogs resources */

Ein PUT auf eine URL mit einem Schrägstrich soll alle Ressourcen ersetzen.

PUT http://example.com/dogs/          /* Replace all the dogs resources */

Ein DELETE in einer URL mit einem Schrägstrich soll alle Ressourcen löschen

DELETE http://example.com/dogs/       /* Deletes all the dogs resources */

Durch einen POST auf eine URL mit einem Schrägstrich soll eine neue Ressource erstellt werden, auf die anschließend zugegriffen werden kann. Um konform zu sein, sollte sich die neue Ressource in diesem Verzeichnis befinden (obwohl viele RESTful-Architekturen hier schummeln).

POST http://example.com/dogs/        /* Creates a new dogs resource (notice singular) */

usw.

Die Wiki-Seite zu diesem Thema scheint es gut zu erklären:

Siehe Beispiel https://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_Web_services .

Martin York
quelle
Es passt auch zum normalen /
Pfad-
4
Was sollte also passieren, wenn Sie auf eine Ressourcengruppe zugreifen, ohne dass das Ende folgt /?
Oberlies
1
@oberlies: Das hängt vom Kontext ab. Es gibt keine festen Regeln, nur Best Practices. Es gibt immer Erwartungen an die Regel und es sollte bedeuten, was Sie erwarten, dass es bedeutet. Im obigen Beispiel: GET http://example.com/dogsGibt möglicherweise Metainformationen zu den Hunden zurück (nicht die Liste selbst, sondern Metainformationen zur Liste der Hunde). Vielleicht oder vielleicht ist es ein Fehler.
Martin York
1
As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.Dies ist nicht der einzige Ort , der vorschlägt, keinen Trainings-Slash zu verwenden
Laiv,
@Laiv Ich bin mit dem Gefühl nicht einverstanden. Aber bitte verlinken Sie einen verbindlicheren Verweis (das ist ein schwacher Link).
Martin York
17
Does anyone know the definitive answer?

Es gibt keine, da es kein offizielles Dokument darüber gibt, was erforderlich ist, damit ein Service als REST-konform eingestuft wird.

Das heißt, ich würde den abschließenden Schrägstrich einfach für die Benutzerfreundlichkeit zulassen. Technisch gesehen könnte dies als Versuch angesehen werden, auf einen Hund mit einer Null-ID zuzugreifen. Ich sehe keinen Benutzer, der diesen Sprung ausführt, es sei denn, er hat ihn in Ihrer Dokumentation gelesen. Ich kann einen Benutzer sehen, der versucht, Code gegen Ihre API zu schreiben und den abschließenden Schrägstrich einfach aus Gewohnheit einzufügen, und mich fragt, warum er eine 404-Antwort erhält, wenn er eine Liste von Hunden haben möchte.

Mike
quelle
Was ist mit DELETE example.com/dogs ?
Benjamin Gruenbaum
Da Hunde die Eltern aller einzelnen Hunde sind, werden durch das Löschen von Hunden alle einzelnen Hunde und sich selbst gelöscht. Wenn Sie das nicht tun, wird Ihre Hypermedia zusammenbrechen
Gaz_Edge
@Gaz_Edge: In REST example.com/dogsist eine Ressource völlig unabhängig von jeder Ressource example.com/dogs/X. Somit muss ein DELETE on example.com/dogsnicht alle Hunde / * löschen (obwohl es das kann, wenn das die Semantik ist). Aber DELETE example.com/dogs/sollte alle Hunde / * löschen.
Martin York
3
Ich würde noch einmal sagen, dass, da es keine endgültigen Regeln dafür gibt, was RESTful ist, was passiert, wenn Sie / dogs oder / dogs / LÖSCHEN, basierend darauf, was Sie von den Verbrauchern Ihrer API erwarten. Ist es wahrscheinlich, dass sie tatsächlich alle Hunde mit einer einzigen Anfrage löschen möchten? Wenn dies der Fall ist, implementieren Sie es wie folgt: Wenn dies nicht der Fall ist, geben Sie eine Antwort 405 Methode nicht zulässig.
Mike
1
Ich weiß, dass dies ein alter Thread ist, aber ich habe mich in letzter Zeit selbst darüber gewundert. Für das, was es wert ist , die OS X Bash - Shell behandelt foo, foo/und foo////identisch. Im Grunde scheint es, leere Pfadsegmente herauszulösen. Wenn Sie also mit Ihrem REST-Service denselben Ansatz verfolgen dogsund dogs/auf dasselbe verweisen würden.
Greg Brown
2

Zwei Wege.

Methode 1

Verwenden Sie immer abschließende Schrägstriche für alle Ressourcen, die untergeordnete Elemente enthalten können.

Betrachten Sie einfach "GET" in einem public_html-Verzeichnis mit Dateien.

Nicht möglich, wenn hallo.html eine Datei ist:

/hello.html
/hello.html/youagain.html

Aber möglich, wenn hallo.html ein Verzeichnis ist:

/hello.html/     (actually /hello.html/index.html)
/hello.html/youagain.html

Wenn "hello.html" also jemals Kinder haben kann, ist es immer und für immer "/hello.html/" und "/hello.html/index.html" (oder einfach "/hello.html/") eine Auflistung dieser Kinder .

Methode 2

Seien Sie clever".

$ find
.
./hello.html
./hello.html/index.html

Der Befehl find kümmert sich nicht um den Typ von hello.html. Verzeichnis oder Datei, wen interessiert es, es ist der Name eines Objekts. Wenn wir "cp youagain.html hello.html" schreiben, kann cp herausfinden, wie man mit hello.html umgeht. cp ist schlau. Ihr Webserver ist auch schlau. Es verfügt über eine Path-Handling-Bibliothek. Es hat Routing. Es kann angeben und Ihnen sagen, ob ein Name ein Objekt oder ein Verzeichnis ist. Es kann bla zu bla umleiten / oder sogar nur die gleiche Antwort für beide liefern. Das ist der Hammer !!! Weg. So viel Technik. Wer würde jemals einfach Pfadzeichenfolgen verketten wollen, wenn wir das alles tun könnten ???

Samuel Danielson
quelle