Jestem zainteresowany udostępnieniem bezpośredniego interfejsu REST do kolekcji dokumentów JSON (pomyśl o CouchDB lub Persevere ). Problem, z którym się spotykam, polega na tym, jak obsłużyć GET
operację na katalogu głównym kolekcji, jeśli kolekcja jest duża.
Jako przykład udaję, że ujawniam Questions
tabelę StackOverflow, w której każdy wiersz jest ujawniony jako dokument (niekoniecznie musi istnieć taka tabela, tylko konkretny przykład sporej kolekcji „dokumentów”). Kolekcja będzie udostępniona na /db/questions
ze zwykłymi CRUD API GET /db/questions/XXX
, PUT /db/questions/XXX
, POST /db/questions
jest w grze. Standardowym sposobem uzyskania całej kolekcji jest, GET /db/questions
ale jeśli naiwnie zrzuci to każdy wiersz jako obiekt JSON, otrzymasz dość spore pobieranie i dużo pracy ze strony serwera.
Rozwiązaniem jest oczywiście stronicowanie. Dojo rozwiązało ten problem w swoim JsonRestStore za pomocą sprytnego rozszerzenia zgodnego z RFC2616, używającego Range
nagłówka z niestandardową jednostką zasięgu items
. Wynikiem jest a, 206 Partial Content
który zwraca tylko żądany zakres. Zaletą tego podejścia w porównaniu z parametrem zapytania jest to, że pozostawia on ciąg zapytania dla ... zapytań (np. GET /db/questions/?score>200
Lub coś takiego, i tak, które byłyby zakodowane %3E
).
To podejście całkowicie pokrywa pożądane przeze mnie zachowanie. Problem polega na tym, że RFC 2616 określa, że w odpowiedzi 206 (moje wyróżnienie):
Żądanie muszą obejmować pole nagłówka Range ( rozdział 14.35 ) wskazując pożądany zakres i mogą mieć włączone pole nagłówka If-Range ( rozdział 14.27 ) do przeprowadzenia żądania warunkowe.
Ma to sens w kontekście standardowego użycia nagłówka, ale stanowi problem, ponieważ chciałbym, aby odpowiedź 206 była domyślna do obsługi naiwnych klientów / przypadkowych ludzi.
Szczegółowo przejrzałem RFC, szukając rozwiązania, ale nie byłem zadowolony z moich rozwiązań i jestem zainteresowany podejściem SO do problemu.
Pomysły, które miałem:
- Wróć
200
zContent-Range
nagłówkiem! - Nie sądzę, żeby to było złe, ale wolałbym bardziej oczywistym wskaźnikiem, że odpowiedź jest tylko Częściową Treścią. - Powrót
400 Range Required
- nie ma specjalnego kodu odpowiedzi 400 dla wymaganych nagłówków, więc domyślny błąd musi być używany i odczytywany ręcznie. Utrudnia to również eksplorację za pomocą przeglądarki internetowej (lub innego klienta, takiego jak Resty). - Użyj parametru zapytania - podejście standardowe, ale mam nadzieję, że zezwolę na zapytania a la Wytrwałość, a to przecina przestrzeń nazw zapytania.
- Po prostu wróć
206
! - Myślę, że większość klientów by się nie wystraszyła, ale wolałbym nie występować przeciwko MUST w RFC - Rozszerz specyfikację! Return
266 Partial Content
- zachowuje się dokładnie jak 206, ale jest odpowiedzią na żądanie, które NIE MOŻE zawieraćRange
nagłówka. Wydaje mi się, że 266 jest na tyle wysokie, że nie powinienem napotkać problemów z kolizją i ma to dla mnie sens, ale nie jestem pewien, czy jest to uważane za tabu, czy nie.
Myślę, że jest to dość powszechny problem i chciałbym zobaczyć, jak robi się to w sposób de facto, więc ani ja, ani ktoś inny nie wymyślamy na nowo koła.
Jaki jest najlepszy sposób ujawnienia pełnej kolekcji za pośrednictwem protokołu HTTP, gdy kolekcja jest duża?
Range = "Range" ":" ranges-specifier
gdzie ta ostatnia w tools.ietf.org/html/rfc2616#section-14.35.1 jest opisana jedynie jako „specyfikator-zakresów bajtów”, który musi zaczynać się od „jednostki-bajtów”, która jest zdefiniowana jako ciąg znaków „bajty ”.
Content-Range
Nagłówek odnosi się do ciała (może być używany z prośbą podczas przesyłania dużych plików itp, lub do odpowiedzi podczas pobierania). Range
Header służy do żądania określonego zakresu. Należy odpowiedzieć, 206
kiedy Range
nagłówek został zawarty w żądaniu. Jeśli tak nie jest, odpowiedź może nadal zawierać Content-Range
nagłówek, ale kod odpowiedzi powinien być 200
. Ten nagłówek wydaje się być idealny do stronicowania.