Ich bin daran interessiert, eine direkte REST-Schnittstelle für Sammlungen von JSON-Dokumenten bereitzustellen (denken Sie an CouchDB oder Persevere ). Das Problem, auf das ich stoße, ist, wie der GET
Vorgang im Sammlungsstamm behandelt wird, wenn die Sammlung groß ist.
Stellen Sie sich als Beispiel vor, ich mache die Questions
Tabelle von StackOverflow verfügbar, in der jede Zeile als Dokument verfügbar gemacht wird (nicht, dass es unbedingt eine solche Tabelle gibt, sondern nur ein konkretes Beispiel für eine umfangreiche Sammlung von 'Dokumenten'). Die Sammlung würde zur Verfügung gestellt wird /db/questions
mit dem üblichen CRUD api GET /db/questions/XXX
, PUT /db/questions/XXX
, POST /db/questions
ist im Spiel. Der Standardweg, um die gesamte Sammlung GET /db/questions
abzurufen, besteht darin, aber wenn dadurch jede Zeile naiv als JSON-Objekt ausgegeben wird, erhalten Sie einen ziemlich umfangreichen Download und viel Arbeit seitens des Servers.
Die Lösung ist natürlich Paging. Dojo hat dieses Problem in seinem JsonRestStore über eine clevere RFC2616-kompatible Erweiterung der Verwendung des Range
Headers mit einer benutzerdefinierten Bereichseinheit gelöst items
. Das Ergebnis ist ein 206 Partial Content
, das nur den angeforderten Bereich zurückgibt. Der Vorteil dieses Ansatzes gegenüber einem Abfrageparameter besteht darin, dass die GET /db/questions/?score>200
Abfragezeichenfolge für ... Abfragen verbleibt (z. B. oder so, und ja, das würde codiert %3E
).
Dieser Ansatz deckt das gewünschte Verhalten vollständig ab. Das Problem ist, dass RFC 2616 dies bei einer 206-Antwort angibt (Hervorhebung von mir):
Die Anforderung MUSS ein Bereichs-Header-Feld ( Abschnitt 14.35 ) enthalten, das den gewünschten Bereich angibt, und KANN ein If-Range-Header-Feld ( Abschnitt 14.27 ) enthalten, um die Anforderung bedingt zu machen.
Dies ist im Zusammenhang mit der Standardverwendung des Headers sinnvoll, stellt jedoch ein Problem dar, da ich möchte, dass die Antwort 206 die Standardeinstellung für naive Clients / zufällige Personen ist.
Ich habe den RFC im Detail durchgesehen und nach einer Lösung gesucht, war aber mit meinen Lösungen unzufrieden und bin daran interessiert, dass SO das Problem aufgreift.
Ideen, die ich hatte:
- Kehre
200
mit einemContent-Range
Header zurück! - Ich denke nicht, dass dies falsch ist, aber ich würde es vorziehen, wenn ein offensichtlicherer Indikator dafür ist, dass die Antwort nur Teilinhalt ist. - Rückgabe
400 Range Required
- Es gibt keinen speziellen 400-Antwortcode für die erforderlichen Header, daher muss der Standardfehler von Hand verwendet und gelesen werden. Dies erschwert auch die Erkundung über einen Webbrowser (oder einen anderen Client wie Resty). - Verwenden Sie einen Abfrageparameter - Der Standardansatz, aber ich hoffe, Abfragen a la Persevere zuzulassen, und dies schneidet in den Abfrage-Namespace.
- Komm einfach zurück
206
! - Ich denke, die meisten Kunden würden nicht ausflippen, aber ich würde lieber nicht gegen ein MUSS im RFC vorgehen - Erweitern Sie die Spezifikation! Return
266 Partial Content
- Verhält sich genau wie 206, ist jedoch eine Antwort auf eine Anfrage, die denRange
Header NICHT enthalten darf. Ich denke, dass 266 hoch genug ist, um nicht auf Kollisionsprobleme zu stoßen, und es macht für mich Sinn, aber ich bin mir nicht sicher, ob dies als tabu angesehen wird oder nicht.
Ich würde denken, dass dies ein ziemlich häufiges Problem ist und ich würde es gerne de facto sehen, damit ich oder jemand anderes das Rad nicht neu erfinden.
Was ist der beste Weg, um eine vollständige Sammlung über HTTP verfügbar zu machen, wenn die Sammlung groß ist?
Range = "Range" ":" ranges-specifier
wo letztere in tools.ietf.org/html/rfc2616#section-14.35.1 lediglich als " Bytebereichs -Spezifizierer" beschrieben wird, der mit "Byte-Einheit" beginnen muss, die als Zeichenfolge "Bytes" definiert ist ".
Content-Range
Header gilt für den Body (kann mit Anfrage beim Hochladen großer Dateien usw. oder als Antwort beim Herunterladen verwendet werden). Der Range
Header wird verwendet, um einen bestimmten Bereich anzufordern. Man sollte antworten, 206
wann der Range
Header in der Anfrage enthalten war. Wenn dies nicht der Content-Range
Fall ist , enthält die Antwort möglicherweise noch einen Header, der Antwortcode sollte jedoch lauten 200
. Dieser Header scheint eigentlich ideal zum Blättern zu sein.