Je suis intéressé à exposer une interface REST directe à des collections de documents JSON (pensez CouchDB ou Persevere ). Le problème que je rencontre est de savoir comment gérer l' GET
opération sur la racine de la collection si la collection est grande.
À titre d'exemple, prétendez que j'expose la Questions
table de StackOverflow où chaque ligne est exposée en tant que document (non pas qu'il existe nécessairement une telle table, juste un exemple concret d'une collection importante de «documents»). La collection sera mis à disposition à /db/questions
la api habituelle CRUD GET /db/questions/XXX
, PUT /db/questions/XXX
, POST /db/questions
est en jeu. Le moyen standard d'obtenir toute la collection est de le faire, GET /db/questions
mais si cela vide naïvement chaque ligne en tant qu'objet JSON, vous obtiendrez un téléchargement assez important et beaucoup de travail de la part du serveur.
La solution est, bien sûr, la pagination. Dojo a résolu ce problème dans son JsonRestStore via une extension intelligente conforme à la RFC2616 d'utilisation de l'en- Range
tête avec une unité de plage personnalisée items
. Le résultat est un 206 Partial Content
qui renvoie uniquement la plage demandée. L'avantage de cette approche par rapport à un paramètre de requête est qu'elle laisse la chaîne de requête pour ... requêtes (par exemple GET /db/questions/?score>200
ou une partie, et oui qui serait encodée %3E
).
Cette approche couvre complètement le comportement que je souhaite. Le problème est que la RFC 2616 spécifie que sur une réponse 206 (c'est moi qui souligne):
La demande DOIT avoir inclus un champ d'en-tête Range ( section 14.35 ) indiquant la gamme souhaitée, et PEUT avoir inclus un champ d'en-tête If-Range ( section 14.27 ) pour rendre la demande conditionnelle.
Cela a du sens dans le contexte de l'utilisation standard de l'en-tête, mais c'est un problème car j'aimerais que la réponse 206 soit la réponse par défaut pour gérer les clients naïfs / les personnes aléatoires explorant.
J'ai parcouru la RFC en détail à la recherche d'une solution, mais je n'ai pas été satisfait de mes solutions et je suis intéressé par la prise en charge du problème par les SO.
Idées que j'ai eues:
- Revenez
200
avec un en-Content-Range
tête! - Je ne pense pas que ce soit faux, mais je préférerais un indicateur plus évident que la réponse n'est qu'un contenu partiel. - Retour
400 Range Required
- Il n'y a pas de code de réponse 400 spécial pour les en-têtes requis, donc l'erreur par défaut doit être utilisée et lue à la main. Cela rend également l'exploration via un navigateur Web (ou un autre client comme Resty) plus difficile. - Utilisez un paramètre de requête - L'approche standard, mais j'espère autoriser les requêtes à la persévérance et cela coupe dans l'espace de noms de la requête.
- Revenez juste
206
! - Je pense que la plupart des clients ne paniqueraient pas, mais je préfère ne pas aller à l'encontre d'un MUST dans la RFC - Prolongez les spécifications! Retour
266 Partial Content
- Se comporte exactement comme 206 mais est en réponse à une demande qui NE DOIT PAS contenir l'en-Range
tête. Je pense que 266 est suffisamment élevé pour que je ne devrais pas rencontrer de problèmes de collision et cela a du sens pour moi, mais je ne sais pas si cela est considéré comme tabou ou non.
Je pense que c'est un problème assez courant et j'aimerais que cela se fasse d'une manière de facto afin que moi ou quelqu'un d'autre ne réinvente pas la roue.
Quelle est la meilleure façon d'exposer une collection complète via HTTP lorsque la collection est volumineuse?
Range = "Range" ":" ranges-specifier
où ce dernier dans tools.ietf.org/html/rfc2616#section-14.35.1 est simplement décrit comme "byte-range-specifier" qui doit commencer par "bytes-unit" qui est défini comme la chaîne "bytes ".
Content-Range
tête s'applique au corps (peut être utilisé avec une requête lors du téléchargement de gros fichiers, etc., ou pour une réponse lors du téléchargement). L'en- Range
tête est utilisé pour demander une certaine plage. Il faut répondre 206
quand l'en- Range
tête a été inclus dans la demande. Si ce n'est pas le cas, la réponse peut toujours inclure un en- Content-Range
tête, mais le code de réponse doit l'être 200
. Cet en-tête semble en fait idéal pour la pagination.