web-dev-qa-db-fra.com

Comment puis-je gérer les limitations de longueur de chaîne de requête HTTP GET tout en voulant rester RESTful?

Comme indiqué dans http://www.boutell.com/newfaq/misc/urllength.html , la chaîne de requête HTTP a une longueur limitée. Il peut être limité par le client (Firefox, IE, ...), le serveur (Apache, IIS, ...) ou les équipements réseau (pare-feu applicatif, ...).

Aujourd'hui, je fais face à ce problème avec un formulaire de recherche. Nous avons développé un formulaire de recherche avec de nombreux champs. Ce formulaire est envoyé au serveur sous forme de requête GET, ce qui me permet de créer un signet pour la page obtenue.

Nous avons tellement de champs que notre chaîne de requête a une longueur de 1100 octets et nous avons un pare-feu qui supprime les requêtes HTTP GET de plus de 1024 octets. Notre administrateur système nous recommande d'utiliser POST à la place afin d'éviter toute limitation.

Bien sûr, POST fonctionnera, mais je ressens vraiment une recherche en tant que GET et non pas un POST. Je pense donc que nous examinerons les noms de nos champs pour nous assurer que la chaîne de requête n'est pas trop longue. Sinon, je serai pragmatique et utiliserai POST.

Mais existe-t-il une faille dans la conception des services RESTful? Si la longueur de la requête GET est limitée, comment puis-je envoyer des objets volumineux à un service Web RESTful? Par exemple, si j’ai un programme qui effectue des calculs à partir d’un fichier et que je souhaite fournir un service Web RESTful comme celui-ci: http://compute.com?content=<base64 file>. Cela ne fonctionnera pas car la chaîne de requête n'a pas une longueur illimitée.

Je suis un peu perplexe ...

72
cbliard

Basé sur votre description, IMHO vous devriez utiliser un POST. POST sert à placer des données sur le serveur et, dans certains cas, à obtenir une réponse. Dans votre cas, vous effectuez une recherche (envoyez une requête au serveur) et obtenez le résultat de cette recherche (récupérez le résultat de la requête).

La définition de GET indique qu'elle doit être utilisée pour récupérer une ressource déjà existante. Par définition, POST consiste à créer une nouvelle ressource. C'est exactement ce que vous faites: créer une ressource sur le serveur et la récupérer! Même si vous ne stockez pas le résultat de la recherche, vous avez créé un objet sur le serveur et l'avez récupéré. Comme PeterMmm l'a déjà dit, vous pouvez le faire avec un POST (créer et stocker le résultat de la requête), puis utiliser un GET pour retracer la requête, mais il est plus pratique de ne faire qu'un POST et d'extraire le résultat. .

J'espère que cela t'aides! :)

50
jmpcm

La spécification HTTP en fait conseille d'utiliser POST lors de l'envoi de données à une ressource } pour le calcul.

Votre recherche ressemble à un calcul, pas à une ressource elle-même. Si vous souhaitez toujours que vos résultats de recherche soient une ressource, vous pouvez créer un jeton pour identifier ce résultat de recherche spécifique et rediriger l'agent d'utilisateur vers cette ressource.

Vous pouvez ensuite supprimer les jetons de résultats de recherche après un certain temps.

Exemple

POST /search
query=something&category=c1&category=c2&...

201 Created
Location: /search/01543164876

puis

GET /search/01543164876

200 Ok
... your results here...

De cette manière, les navigateurs et les mandataires peuvent toujours mettre en cache les résultats de la recherche, mais vous soumettez vos paramètres de requête à l'aide de POST.

MODIFIER 

Pour plus de précision, 01543164876 représente ici un identifiant unique pour la ressource représentant votre recherche. Ces 2 requêtes signifient essentiellement: créer un nouvel objet de recherche avec ces critères, puis récupérer les résultats associés à l'objet de recherche créé.

Cet identifiant peut être un identifiant unique généré pour chaque nouvelle demande. Cela signifierait que votre serveur perdra des objets "de recherche" et que vous devrez les nettoyer régulièrement avec une stratégie de mise en cache. 

Ou bien ce peut être un hachage de tous les critères de recherche représentant réellement la recherche demandée par l'utilisateur. Cela vous permet de réutiliser des identifiants, car la recréation d'une recherche renvoie un identifiant existant qui peut être (ou non) déjà mis en cache.

56
Vincent Robert

La confusion autour de GET est une limitation du navigateur. Si vous créez une interface RESTful pour une application A2A ou P2P, la longueur de votre GET n'est pas limitée. 

Maintenant, si vous souhaitez utiliser un navigateur pour afficher votre interface RESTful (pendant le développement/le débogage), vous rencontrerez cette limite, mais il existe des outils pour le contourner. 

5
ken kranz

REST est une manière de faire les choses, pas un protocole. Même si vous n'aimez pas POST quand c'est vraiment un GET, cela fonctionnera.

Si vous voulez/devez rester avec la définition "standard" de GET, POST, etc. que vous pouvez envisager de POST comme une requête, cette requête sera stockée sur le serveur avec un identifiant de requête et sera demandée ultérieurement avec GET par id.

5
PeterMmm

En ce qui concerne votre exemple: http://compute.com?content={base64file}, j'utiliserais POST parce que vous téléchargez "quelque chose" à calculer. Pour moi, ce "quelque chose" ressemble plus à une ressource qu’à un simple paramètre. 

Contrairement à cela dans la recherche habituelle, je commencerais par rester avec GET et des paramètres. Vous aidez tellement les api-clients à tester et à jouer avec votre api. Faites en sorte que l'accès en lecture seule (qui dans la plupart des cas représente la majorité du trafic) soit aussi simple que possible!

Mais le dilemme des grandes chaînes de requête est une limitation valide de GET. Ici, je voudrais être pragmatique, tant que vous n'atteignez pas cette limite avec GET et url-params. Cela fonctionnera dans 98% des cas de recherche. Agissez uniquement si vous atteignez cette limite, puis introduisez également POST avec une charge utile (avec le type mime Content-Type: application/x-www-form-urlencoded).

Avez-vous d'autres exemples concrets?

3
manuel aldana

Cinq ans plus tard, il semble exister une autre option viable - utilisez le corps du message de GET. J'inclus cette réponse comme alternative à toutes les suggestions ci-dessus, même si elle a ses propres limites (faire des recherches). 

0
G. Stoynev

C'est facile. Utilisez POST. HTTP n'impose pas de limite à la longueur de l'URL pour GET, mais les serveurs le font. Soyez pragmatique et contournez-le avec un POST. 

Vous pouvez également utiliser un corps GET (autorisé), mais c'est un double inconvénient en ce sens que l'utilisation n'est pas correcte et que des problèmes de serveur risquent de se produire. 

0
Rick O'Shea