HTTP POST avec des parameters de requête d’URL – bonne idée ou pas?

Je conçois une API pour passer par HTTP et je me demande si l’utilisation de la commande HTTP POST, mais uniquement avec les parameters de requête d’URL et l’absence de corps de requête, est une bonne solution.

Considérations:

  • “Good Web Design” nécessite l’envoi d’actions non idempotentes via POST. C’est une action non idempotente.
  • Il est plus facile de développer et de déboguer cette application lorsque les parameters de la requête 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 demande un peu plus de travail, par exemple un en Content-Length: 0 tête Content-Length: 0 doit être explicitement ajouté.
  • Il me semble également qu’un POST sans corps est un peu en contradiction avec les attentes de la plupart des développeurs et des frameworks HTTP.

Existe-t-il d’autres pièges ou avantages liés à l’envoi de parameters sur une requête POST via la requête URL plutôt que le corps de la requête?

Edit: La raison en 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 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, de manière à ce que l’utilisateur soit informé du fait qu’une action potentiellement dangereuse est demandée.

Les méthodes peuvent également avoir la propriété “idempotence” dans la mesure où (hormis les problèmes d’erreur ou d’expiration) les effets secondaires de N> 0 requêtes identiques sont les mêmes que pour une requête unique. Les méthodes GET, HEAD, PUT et DELETE partagent cette propriété. De plus, les méthodes OPTIONS et TRACE NE DOIVENT PAS avoir d’effets secondaires et sont donc insortingnsèquement idempotentes.

    Si votre action n’est pas idempotente, vous devez alors utiliser POST . Si vous ne le faites pas, vous demandez simplement des problèmes sur toute la ligne. GET méthodes GET , PUT et DELETE doivent être idempotentes. Imaginez ce qui se passerait dans votre application si le client était en train de pré-extraire toutes les requêtes GET possibles 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 scope de la requête en cours. Typiquement, les chaînes de requête sont utilisées pour sortinger ou filtrer une requête GET (comme ?page=1&sort=title ), mais je suppose que cela a du sens de limiter également la scope (peut-être comme ?action=delete&id=5 ).

    Tout le monde a raison: respectez le POST pour les demandes non idempotentes.

    Qu’en est-il de l’utilisation d’une chaîne de requête URI et du contenu de la demande? Eh bien, c’est HTTP valide (voir note 1), alors pourquoi pas!

    Il est également parfaitement logique que les URL, y compris leur partie de chaîne de requête, servent à localiser les ressources. Alors que les verbes de méthode HTTP (POST – et son contenu de requête facultatif) servent à spécifier des actions ou à faire avec les ressources. Celles-ci devraient être des préoccupations orthogonales. (Mais ce ne sont pas des problèmes magnifiquement orthogonaux 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 parameters de requête et le contenu sont mutuellement exclusifs pour un serveur HTTP qui accepte les requêtes POST ou PUT. Ainsi, tout serveur est libre d’accepter les deux. Si vous écrivez sur le serveur, rien ne vous empêche d’accepter les deux (sauf peut-être un cadre rigide). Généralement, le serveur peut interpréter les chaînes de requête en fonction des règles souhaitées. Il peut même les interpréter avec une logique conditionnelle faisant référence à d’autres en-têtes comme Content-Type, ce qui conduit à la note 2:

    Remarque 2: si les navigateurs Web accèdent principalement à votre application Web et que application / x-www-form-urlencoded est le type de contenu qu’ils publient, vous devez suivre les règles de 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 parameters et non un emplacement de ressource. [C’est le même point d’utilité que le seigneur puissant a soulevé; Il peut être difficile d’utiliser des formulaires Web pour afficher du contenu sur votre serveur. Juste expliqué un peu différemment.]

    Note 3: à quoi servent les chaînes de requête? La RFC 3986 définit les chaînes de requête HTTP comme une partie d’URI qui fonctionne comme un moyen non hiérarchique de localiser une ressource.

    Au cas où les lecteurs qui poseraient cette question souhaiteraient savoir quelle est la bonne architecture RESTful: le modèle d’architecture RESTful ne nécessite pas que les schémas d’URI fonctionnent d’une manière spécifique. L’architecture RESTful concerne d’autres propriétés du système, telles que 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, obtenir 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 quant à la façon dont les ressources sont localisées ).

    Note finale: parfois, les parameters de requête sont utilisés pour d’autres choses, qui ne sont ni la localisation des ressources, ni le contenu de l’encodage. Avez-vous déjà vu un paramètre de requête comme ‘PUT = true’ ou ‘POST = true’? Ce sont des solutions de contournement pour les navigateurs qui ne vous permettent pas d’utiliser les méthodes PUT et POST. Bien que ces parameters 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 en esprit .

    Vous voulez des raisons? En voici un:

    Un formulaire Web ne peut pas être utilisé pour envoyer une requête à une page utilisant un mélange de GET et de POST. Si vous définissez la méthode du formulaire sur GET, tous les parameters sont dans la chaîne de requête. Si vous définissez la méthode du formulaire sur POST, tous les parameters se trouvent dans le corps de la requête.

    Source: norme HTML 4.01, section 17.13 Soumission du formulaire

    Du sharepoint vue des programmes, pour le client, il regroupe les parameters, les ajoute à l’URL et effectue un POST par rapport à un GET. Côté serveur, il évalue les parameters entrants de la chaîne de requête au lieu des octets publiés. Fondamentalement, c’est un lavage.

    Les avantages et les inconvénients peuvent se présenter dans la manière dont les plates-formes client spécifiques fonctionnent avec les routines POST et GET dans leur stack réseau, ainsi que dans la manière dont le serveur Web traite ces requêtes. Selon votre implémentation, une approche peut être plus efficace que l’autre. Sachant que cela guiderait votre décision ici.

    Néanmoins, du sharepoint vue d’un programmeur, je préfère autoriser soit un POST avec tous les parameters du corps, soit un GET avec tous les parameters de l’URL, et en ignorant explicitement les parameters url avec toute requête POST. Cela évite la confusion.

    Je pense qu’il pourrait toujours être très utile d’avoir des arguments de requête qui identifient la ressource sur l’URL tout en gardant la charge de contenu confinée au corps du POST. Cela semblerait séparer les considérations de “Qu’est-ce que j’envoie?” contre “Qui est-ce que je l’envoie?”.

    Le camp REST a quelques principes directeurs que nous pouvons utiliser pour standardiser la façon dont nous utilisons les verbes HTTP. Ceci est utile lorsque vous construisez des API RESTful comme vous le faites.

    En bref: GET doit être en lecture seule, c’est-à-dire qu’il n’ya 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 POST est mauvais et les avertira, car le but de POST est de modifier l’état du serveur (p. Ex. Payer des biens à la caisse) et vous ne voudrez probablement pas le faire deux fois!

    Comparez à un GET que vous pouvez faire 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 transmettre des données dans l’URL et non dans le corps. Voir cette question similaire pour des vues supplémentaires sur l’ensemble du concept POST + GET.