Ich habe in letzter Zeit einige umfangreiche Untersuchungen zu dieser und anderen Fragen im Zusammenhang mit REST-Paging durchgeführt und fand es konstruktiv, einige meiner Ergebnisse hier hinzuzufügen. Ich erweitere die Frage ein wenig, um Gedanken zum Paging sowie zur Zählung einzubeziehen, da sie eng miteinander verbunden sind.
Überschriften
Die Paging-Metadaten sind in Form von Antwortheadern in der Antwort enthalten. Der große Vorteil dieses Ansatzes besteht darin, dass die Antwortnutzlast selbst nur die tatsächliche Datenanforderung ist, nach der gefragt wurde. Erleichterung der Verarbeitung der Antwort für Clients, die nicht an den Paging-Informationen interessiert sind.
Es gibt eine Reihe von (Standard- und benutzerdefinierten) Headern, die in freier Wildbahn verwendet werden, um Paging-bezogene Informationen zurückzugeben, einschließlich der Gesamtzahl.
X-Total-Count
X-Total-Count: 234
Dies wird in einigen APIs verwendet, die ich in freier Wildbahn gefunden habe. Es gibt auch NPM-Pakete zum Hinzufügen von Unterstützung für diesen Header zu z. B. Loopback. In einigen Artikeln wird empfohlen, auch diesen Header festzulegen.
Es wird häufig in Kombination mit dem Link
Header verwendet. Dies ist eine ziemlich gute Lösung für das Paging, es fehlen jedoch die Informationen zur Gesamtanzahl.
Verknüpfung
Link: </TheBook/chapter2>;
rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
</TheBook/chapter4>;
rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel
Ich bin der Meinung, dass nach allgemeiner Lektüre zu diesem Thema der allgemeine Konsens darin besteht, den Link
Header zu verwenden, um Paging-Links für Clients bereitzustellen rel=next
, die rel=previous
usw. verwenden. Das Problem dabei ist, dass es an Informationen darüber mangelt, wie viele Datensätze insgesamt vorhanden sind warum viele APIs dies mit dem X-Total-Count
Header kombinieren .
Alternativ verwenden einige APIs und z. B. der JsonApi- Standard das Link
Format, fügen die Informationen jedoch in einem Antwortumschlag anstelle eines Headers hinzu. Dies vereinfacht den Zugriff auf die Metadaten (und schafft einen Ort zum Hinzufügen der Gesamtanzahlinformationen) auf Kosten einer zunehmenden Komplexität des Zugriffs auf die tatsächlichen Daten selbst (durch Hinzufügen eines Umschlags).
Inhaltsbereich
Content-Range: items 0-49/234
Gefördert durch einen Blog-Artikel namens Range Header, wähle ich Sie (für die Paginierung)! . Der Autor spricht sich stark dafür aus, die Überschriften Range
und Content-Range
für die Paginierung zu verwenden. Wenn wir den RFC in diesen Headern sorgfältig lesen , stellen wir fest, dass die Erweiterung ihrer Bedeutung über Bytebereiche hinaus vom RFC tatsächlich vorweggenommen wurde und ausdrücklich zulässig ist. Wenn der Bereichskopf im Kontext von items
anstelle von verwendet wird bytes
, können wir sowohl einen bestimmten Bereich von Elementen anfordern als auch angeben, auf welchen Bereich des Gesamtergebnisses sich die Antwortelemente beziehen. Dieser Header bietet auch eine großartige Möglichkeit, die Gesamtzahl anzuzeigen. Und es ist ein echter Standard, der Paging meistens eins zu eins zuordnet. Es wird auch in freier Wildbahn verwendet .
Briefumschlag
Viele APIs, einschließlich der von unserer bevorzugten Q & A-Website, verwenden einen Umschlag , einen Wrapper um die Daten, mit dem Metainformationen zu den Daten hinzugefügt werden. Auch OData und JsonApi Standards einen .
Der große Nachteil (imho) ist, dass die Verarbeitung der Antwortdaten komplexer wird, da die tatsächlichen Daten irgendwo im Umschlag gefunden werden müssen. Es gibt auch viele verschiedene Formate für diesen Umschlag und Sie müssen das richtige verwenden. Es ist bezeichnend, dass die Antwortumschläge von OData und JsonApi sehr unterschiedlich sind, wobei OData an mehreren Stellen in der Antwort Metadaten einmischt.
Separater Endpunkt
Ich denke, dies wurde in den anderen Antworten ausreichend behandelt. Ich habe nicht so viel untersucht, weil ich den Kommentaren zustimme, dass dies verwirrend ist, da Sie jetzt mehrere Arten von Endpunkten haben. Ich finde es am schönsten, wenn jeder Endpunkt eine (Sammlung von) Ressourcen darstellt.
Weitere Gedanken
Wir müssen nicht nur die Paging-Metainformationen in Bezug auf die Antwort kommunizieren, sondern dem Client auch erlauben, bestimmte Seiten / Bereiche anzufordern. Es ist interessant, auch diesen Aspekt zu betrachten, um eine kohärente Lösung zu erhalten. Auch hier können wir Header (der Range
Header scheint sehr geeignet zu sein) oder andere Mechanismen wie Abfrageparameter verwenden. Einige Leute befürworten die Behandlung von Seiten der Ergebnisse als separate Ressourcen, der Sinn in einigen Anwendungsfällen machen kann (zB /books/231/pages/52
. Ich landete eine wilde Reihe von häufig verwendeten Anforderungsparametern Auswahl wie pagesize
, page[size]
und limit
usw. zusätzlich zur Unterstützung der Range
Header (und als Anforderungsparameter auch).