Je conçois une API pour parcourir HTTP et je me demande si l'utilisation de la commande HTTP POST, mais avec des paramètres de requête URL uniquement et sans corps de demande, est une bonne façon de procéder.
Considérations:
- Une «bonne conception Web» requiert que des actions non idempotentes soient envoyées via POST. Il s'agit d'une action non idempotente.
- Il est plus facile de développer et de déboguer cette application lorsque les paramètres de demande sont présents dans l'URL.
- L'API n'est pas destinée à une utilisation généralisée.
- Il semble que faire une requête POST sans corps prendra un peu plus de travail, par exemple un en-
Content-Length: 0
tête doit être explicitement ajouté. - Il me semble également qu'un POST sans corps est un peu contraire aux attentes de la plupart des développeurs et des frameworks HTTP.
Y a-t-il d'autres pièges ou avantages à envoyer des paramètres sur une requête POST via la requête URL plutôt que le corps de la requête?
Edit: La raison pour laquelle cela est envisagé est que les opérations ne sont pas idempotentes et ont des effets secondaires autres que la récupération. Voir la spécification HTTP :
En particulier, la convention a été établie que les méthodes GET et HEAD NE DEVRAIENT PAS avoir la signification de prendre une action autre que la récupération. Ces méthodes doivent être considérées comme «sûres». Cela permet aux agents utilisateurs de représenter d'autres méthodes, telles que POST, PUT et DELETE, d'une manière spéciale, afin que l'utilisateur soit informé du fait qu'une action potentiellement dangereuse est demandée.
...
Les méthodes peuvent également avoir la propriété d '"idempotence" en ce que (à part les problèmes d'erreur ou d'expiration) les effets secondaires de N> 0 requêtes identiques sont les mêmes que pour une seule requête. Les méthodes GET, HEAD, PUT et DELETE partagent cette propriété. De plus, les méthodes OPTIONS et TRACE NE DEVRAIENT PAS avoir d'effets secondaires et sont donc intrinsèquement idempotentes.
Réponses:
Si votre action n'est pas idempotente, alors vous DEVEZ l' utiliser
POST
. Si vous ne le faites pas, vous demandez simplement des problèmes sur toute la ligne.GET
,PUT
Et lesDELETE
méthodes sont nécessaires pour être idempotent. Imaginez ce qui se passerait dans votre application si le client récupérait chaqueGET
demande possible pour votre service - si cela provoquait des effets secondaires visibles pour le client, alors quelque chose ne va pas.Je suis d'accord que l'envoi d'un
POST
avec une chaîne de requête mais sans corps semble étrange, mais je pense que cela peut être approprié dans certaines situations.Considérez la partie requête d'une URL comme une commande à la ressource pour limiter la portée de la demande actuelle. En règle générale, les chaînes de requête sont utilisées pour trier ou filtrer une
GET
demande (comme?page=1&sort=title
), mais je suppose qu'il est logiquePOST
de limiter également la portée (peut-être comme?action=delete&id=5
).la source
/action?response_format=json
)Tout le monde a raison: restez avec POST pour les demandes non idempotentes.
Qu'en est-il de l'utilisation à la fois d'une chaîne de requête URI et d'un contenu de demande? Eh bien c'est HTTP valide (voir note 1), alors pourquoi pas?!
C'est aussi parfaitement logique: les URL, y compris leur partie chaîne de requête, servent à localiser les ressources. Alors que les verbes de méthode HTTP (POST - et son contenu de demande facultatif) servent à spécifier des actions, ou quoi faire avec des ressources. Ce devraient être des préoccupations orthogonales. (Mais, ce ne sont pas de belles préoccupations orthogonales pour le cas particulier de ContentType = application / x-www-form-urlencoded, voir la note 2 ci-dessous.)
Remarque 1: la spécification HTTP (1.1) n'indique pas que les paramètres de requête et le contenu s'excluent mutuellement pour un serveur HTTP qui accepte les requêtes POST ou PUT. Ainsi, tout serveur est libre d'accepter les deux. Autrement dit, si vous écrivez le serveur, rien ne vous empêche de choisir d'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'il souhaite. Il peut même les interpréter avec une logique conditionnelle qui fait également référence à d'autres en-têtes comme Content-Type, ce qui conduit à la note 2:
Remarque 2: si un navigateur web est la façon dont les gens primaire accèdent à votre application web et application / x-www-form-urlencoded est le type de contenu qu'ils affichent, vous devez suivre les règles pour ce type de contenu. Et les règles d'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 comme un emplacement de ressource. [C'est le même point d'utilité soulevé par Powerlord; qu'il peut être difficile d'utiliser des formulaires Web pour publier du contenu sur votre serveur. Juste expliqué un peu différemment.]
Remarque 3: à quoi servent les chaînes de requête à l'origine? La RFC 3986 définit les chaînes de requête HTTP comme une partie URI qui fonctionne comme un moyen non hiérarchique de localiser une ressource.
Dans le cas où les lecteurs posant cette question souhaitent demander ce qu'est une bonne architecture RESTful: le modèle d'architecture RESTful ne nécessite pas que les schémas URI fonctionnent d'une manière spécifique. L'architecture RESTful se préoccupe des autres propriétés du système, comme la mise en cache des ressources, la conception des ressources elles-mêmes (leur comportement, leurs capacités et leurs représentations), et si l'idempotence est satisfaite. Ou en d'autres termes, réaliser une conception hautement compatible avec le protocole HTTP et son ensemble de verbes de méthode HTTP. :-) (En d'autres termes, l'architecture RESTful n'est pas très presciptive avec la façon dont les ressources sont localisées .)
Remarque finale: parfois, les paramètres de requête sont utilisés pour d'autres choses encore, qui ne sont ni la recherche de ressources ni l'encodage de contenu. Avez-vous déjà vu un paramètre de requête comme «PUT = true» ou «POST = true»? Il s'agit de solutions de contournement 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 d'URL (sur le fil), je soutiens qu'ils ne font pas partie de la requête de l'URL dans l'esprit .
la source
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 sur GET, tous les paramètres se trouvent dans la chaîne de requête. Si vous définissez la méthode du formulaire sur POST, tous les paramètres se trouvent dans le corps de la demande.
Source: norme HTML 4.01, section 17.13 Soumission de formulaire
la source
method
est POST, il n'est pas question de modifier l'URI dans le formulaireaction
. Et tout URI peut bien sûr déjà contenir une partie de chaîne de requête./Books?bookCode=1234
. Le serveur Web recevra des variables de formulaire POST et une chaîne de requête.D'un point de vue programmatique, pour le client, il empaquette les paramètres et les ajoute à l'url et effectue un POST par rapport à un GET. Côté serveur, il évalue les paramètres entrants de la chaîne de requête au lieu des octets publiés. Fondamentalement, c'est un lavage.
Il pourrait y avoir des avantages / inconvénients dans la façon dont des plates-formes clientes spécifiques fonctionnent avec les routines POST et GET dans leur pile réseau, ainsi que dans la façon dont le serveur Web traite ces demandes. Selon votre implémentation, une approche peut être plus efficace que l'autre. Savoir que cela guiderait 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 d'URL avec toute demande POST. Cela évite la confusion.
la source
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 du POST. Cela semblerait séparer les considérations de "Qu'est-ce que j'envoie?" contre "À qui dois-je l'envoyer?".
la source
Le camp REST a quelques principes directeurs que nous pouvons utiliser pour normaliser la façon dont nous utilisons les verbes HTTP. Cela est utile lors de la construction des API RESTful comme vous le faites.
En un mot: GET devrait être en lecture seule, 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 modifie 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 POST est mauvais et met en garde contre cela, car l'intention du POST est de modifier l'état du serveur (par exemple, payer les marchandises à la caisse), et vous ne voudrez probablement pas le faire deux fois!
Comparez avec un GET que vous pouvez faire souvent comme vous le souhaitez (idempotent).
la source
Je suis d'accord - il est probablement plus sûr d'utiliser une demande GET si vous passez simplement des données dans l'URL et non dans le corps. Voir cette question similaire pour quelques vues supplémentaires sur l'ensemble du concept POST + GET.
la source