HTTP POST avec les paramètres de requête D'URL - bonne idée ou pas?
je suis en train de concevoir une API pour aller sur HTTP et je me demande si l'utilisation de la commande HTTP POST, mais avec des paramètres de requête URL SEULEMENT et aucun corps de requête, est une bonne façon d'aller.
considérations:
- "Bonne conception de sites Web de" exige non la quantité des actions pour être envoyés par la POSTE. C'est une action non-idempotent.
- il est plus facile de développer et de déboguer cette application lorsque les paramètres de la requête sont présents dans L'URL.
- L'IPA n'est pas destiné à un usage généralisé.
- il semble que faire une requête POST sans corps prendra un peu plus de travail, par exemple un en-tête
Content-Length: 0
doit être explicitement ajouté. - il me semble aussi qu'un POST sans corps est un peu contraire aux attentes de la plupart des développeurs et des cadres HTTP.
y a-t-il d'autres pièges ou avantages à l'envoi de paramètres sur une demande POST via le Requête URL plutôt que le corps de la requête?
Edit: la raison pour laquelle ceci est considéré est que les opérations ne sont pas idempotent et ont des effets secondaires autres que la récupération. Voir la spécification HTTP :
En particulier, la convention a été établi que L'EEG et la tête les méthodes ne devraient pas avoir importance de l'action autre de récupération. Ces méthodes devraient être considéré comme "sûr." Cela permet à l'utilisateur agents représentant d'autres méthodes, comme poster, mettre et supprimer, dans un de façon particulière, de sorte que l'utilisateur soit conscient du fait que, éventuellement, un des mesures dangereuses sont demandées.
...
méthodes peuvent également avoir la propriété de "idempotence" qui (en dehors de problèmes d'erreur ou d'expiration) effets secondaires de N > 0 identique les demandes sont les mêmes que pour un seul demande. Les méthodes GET, HEAD, PUT et supprimer partager cette propriété. Également, les OPTIONS de méthodes et de tracer devraient PAS d'effets secondaires, et sont donc intrinsèquement idempotent.
7 réponses
si votre action n'est pas idempotent, alors vous doit utiliser POST
. Si tu ne le fais pas, tu cherches les ennuis. Les méthodes GET
, PUT
et DELETE
sont et doivent être idempotent. Imaginez ce qui se produirait dans votre application si le client était pré-fetch chaque demande GET
possible pour votre service -- si cela causerait des effets secondaires visibles pour le client, puis quelque chose de mauvais.
je suis d'accord que l'envoi d'un POST
avec une chaîne de requête mais sans un corps semble étrange, mais je pense qu'il peut être approprié dans certaines situations.
pense à la partie requête d'une URL comme une commande à la ressource pour limiter la portée de la requête courante. Typiquement, les chaînes de requête sont utilisées pour trier ou filtrer une requête GET
(comme ?page=1&sort=title
) mais je suppose qu'il est logique sur un POST
de limiter également la portée (peut-être comme ?action=delete&id=5
).
tout le monde a raison: coller avec le POST pour les requêtes non-idempotent.
Qu'en est-il de l'utilisation d'une chaîne de requête URI et du contenu de la requête? Eh bien, il est valide HTTP (voir note 1), alors pourquoi pas!
il est également parfaitement logique: les URLs, y compris leur partie de chaîne de requête, sont pour localiser ressources. Tandis que les verbes de méthode HTTP (POST - et son contenu de requête optionnel) sont pour spécifier des actions, ou que faire avec des ressources. Celles-ci doivent être orthogonales préoccupations. (Mais, ils ne sont pas de belles préoccupations orthogonales pour le cas spécial de ContentType=application / x-www-form-urlencoded, voir la note 2 ci-dessous.)
Note 1: la spécification HTTP (1.1) n'indique pas que les paramètres de requête et le contenu sont mutuellement exclusifs pour un serveur HTTP qui accepte les requêtes POST ou PUT. Ainsi, n'importe quel serveur est libre d'accepter les deux. I. e. si vous écrivez le serveur il n'y a rien pour vous empêcher de vous choisir à accepter les deux (sauf peut-être un cadre rigide). Généralement, le serveur peut interpréter les chaînes de requête selon les règles qu'elle veut. Il peut même les interpréter avec une logique conditionnelle qui se réfère à d'autres en-têtes comme Content-Type aussi, ce qui conduit à la Note 2:
Note 2: si un navigateur web est la principale façon dont les gens accèdent à votre application web, et application / x-www-form-urlencoded est le contenu-Type qu'ils vous postez, puis vous devrait suivre les règles pour ce type de contenu. Et les règles pour application / x-www-form-urlencoded sont beaucoup plus spécifiques (et franchement inhabituelles): dans ce cas, vous devez interpréter L'URI comme un ensemble de paramètres, et non pas une localisation de ressource. [C'est le même point D'utilité Powerlord soulevé; qu'il peut être difficile d'utiliser des formulaires web pour poster du contenu à votre serveur. J'ai juste expliqué un peu différemment.]
Note 3: les chaînes de requête à l'origine? La RFC 3986 définit les chaînes de requête HTTP comme une partie D'URI qui fonctionne comme une façon non hiérarchique de localiser une ressource.
dans le cas où les lecteurs posant cette question souhaitent demander ce qui est une bonne architecture reposante: le modèle D'architecture reposante ne nécessite pas URI schémas à travailler d'une manière spécifique. L'architecture reposante se préoccupe avec d'autres propriétés du système, comme la cachéabilité des ressources, la conception des ressources elles-mêmes (leurs le comportement, les capacités et les représentations), et si idempotence est satisfait. Ou en d'autres termes, réaliser un design qui est hautement compatible avec le protocole HTTP et son ensemble de verbes de méthode HTTP. :- ) (En d'autres termes, RESTful architecture n'est pas très préscitive avec la façon dont les ressources sont situé .)
note finale: parfois les paramètres de requête sont utilisés pour d'autres choses encore, qui ne sont ni la localisation des ressources ni l'encodage du contenu. Jamais vu un paramètre de requête comme 'PUT=true' ou 'POST=true'? Ce sont des solutions de rechange pour les navigateurs qui ne vous permettent pas d'utiliser les méthodes PUT et POST. Bien que ces paramètres soient considérés comme faisant partie de la chaîne de requête de L'URL (sur le fil), je soutiens qu'ils ne font pas partie de la requête de L'URL dans l'esprit .
tu veux des raisons? En voici un:
un formulaire web ne peut pas être utilisé pour envoyer une demande à une page qui utilise un mélange de GET et POST. Si vous définissez la méthode du formulaire pour obtenir, tous les paramètres sont dans la chaîne de requête. Si vous définissez la méthode du formulaire à afficher, tous les paramètres sont dans le corps de la requête.
Source: HTML 4.01 standard, section 17.13 formulaire de soumission
d'un point de vue programmatique, pour le client, il s'agit d'empaqueter les paramètres et de les ajouter à l'url et de mener un POST vs. un GET. Du côté serveur, il évalue les paramètres entrants à partir du querystring au lieu des octets affichés. En gros, c'est un lavage.
où il pourrait y avoir des avantages/inconvénients pourrait être dans la façon dont les plates-formes client spécifiques fonctionnent avec la poste et obtenir des routines dans leur pile de réseau, ainsi que la façon dont le serveur web traite avec ces demandes. Selon votre mise en œuvre, une approche peut être plus efficace que l'autre. Sachant guider votre décision ici.
néanmoins, du point de vue d'un programmeur, je préfère autoriser soit un POST avec tous les paramètres dans le corps, soit un GET avec tous les paramètres sur l'url, et ignorer explicitement les paramètres de l'url avec n'importe quelle requête POST. Il permet d'éviter la confusion.
je pense qu'il pourrait encore être assez reposant d'avoir des arguments de requête qui identifient la ressource sur L'URL tout en gardant la charge utile de contenu confinée au corps de poste. Cela semble séparer les considérations de " Qu'est-ce que j'envoie?"par rapport à "Qui suis-je l'envoyer?".
le REST camp ont quelques principes directeurs que nous pouvons utiliser pour normaliser la façon dont nous utilisons les verbes HTTP. Ceci est utile lors de la construction D'API RESTful comme vous le faites.
en un mot: GET doit être lu uniquement, c'est-à-dire n'avoir aucun effet sur l'état du serveur. POST est utilisé pour créer une ressource sur le serveur. PUT est utilisé pour mettre à jour ou créer une ressource. DELETE est utilisé pour supprimer une ressource.
en d'autres termes, si votre action API change l'état du serveur, REST nous conseille D'Utiliser POST / PUT / DELETE, mais pas GET.
les agents utilisateurs comprennent généralement que faire plusieurs messages est mauvais et préviendra contre cela, parce que L'intention de la poste est de modifier l'état du serveur (par exemple. payer pour les marchandises à la caisse), et vous ne voulez probablement pas faire cela deux fois!
comparez à un GET que vous pouvez faire un souvent comme vous le souhaitez (idempotent).
je suis d'accord - il est probablement plus sûr d'utiliser une requête GET si vous ne faites que passer des données dans L'URL et pas dans le corps. Voir cette question similaire pour quelques vues supplémentaires sur L'ensemble du concept POST+GET.