HTTP POST avec paramètres de requête d'URL & # 8212; bonne idée ou pas? [fermé]

StackOverflow https://stackoverflow.com/questions/611906

  •  03-07-2019
  •  | 
  •  

Question

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 paramètres de requête d'URL et l'absence de corps de requête, est un bon choix.

Considérations:

  • " Bon design Web " nécessite que les actions non idempotentes soient envoyées via POST. Ceci est une action non idempotente.
  • Il est plus facile de développer et de déboguer cette application lorsque les paramètres de la 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 demande POST sans corps prenne un peu plus de travail, par exemple. un en-tête Content-Length: 0 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 cadres HTTP.

Existe-t-il d'autres avantages ou inconvénients à envoyer des paramètres sur une requête POST via la requête URL plutôt que le corps de la requête?

Modifier: 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é   établi que l’EEG et la HEAD   méthodes NE DEVRAIT PAS avoir la   importance de prendre une action autre   que la récupération. Ces méthodes doivent   être considéré comme "sûr". Cela permet à l'utilisateur   des agents pour représenter d'autres méthodes,   tels que POST, PUT et DELETE, dans un   manière spéciale, de sorte que l'utilisateur est fait   conscient du fait qu'un possible   une action dangereuse est demandée.

     

...

     

Les méthodes peuvent aussi avoir la propriété de   "idempotence" en cela (à part   problèmes d’erreur ou d’expiration) le   effets secondaires de N > 0 identique   les demandes sont les mêmes que pour un seul   demande. Les méthodes GET, HEAD, PUT   et DELETE partagent cette propriété. Également,   les méthodes OPTIONS et TRACE DEVRAIENT   PAS avoir d'effets secondaires, et sont donc   intrinsèquement idempotent.

Était-ce utile?

La solution

Si votre action n'est pas idempotente, alors vous devez utiliser POST . Si vous ne le faites pas, vous ne faites que demander des ennuis en bout de ligne. Les méthodes GET , PUT et DELETE sont requises pour être idempotentes. Imaginez ce qui se produirait dans votre application si le client effectuait une pré-extraction de toutes les demandes GET possibles pour votre service - si cela pouvait entraîner des effets secondaires visibles pour le client, il se passait un problème.

Je conviens 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 de la ressource pour limiter la portée de la requête en cours. En règle générale, 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 que cela a du sens pour un POST . pour limiter également la portée (peut-être comme ? action = delete & id = 5 ).

Autres conseils

Tout le monde a raison: respectez POST pour les requêtes non idempotentes.

Pourquoi ne pas utiliser à la fois une chaîne de requête URI et un contenu de requête? Eh bien, c’est HTTP valide (voir note 1), alors pourquoi pas!

C’est également parfaitement logique: les URL, y compris leur partie chaîne de requête, servent à localiser des ressources. Tandis que les verbes de méthode HTTP (POST - et son contenu de requête facultatif) permettent de spécifier des actions, ou quoi faire avec les ressources . Ce devrait être des préoccupations orthogonales. (Mais, ce ne sont pas des préoccupations parfaitement orthogonales dans le cas spécial 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 acceptant les requêtes POST ou PUT. Ainsi, tout serveur est libre d'accepter les deux. C'est à dire. si vous écrivez le serveur, rien ne vous empêche de choisir d'accepter les deux (sauf peut-être un cadre inflexible). En règle générale, 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 tels que Content-Type également, ce qui conduit à la Note 2:

Remarque 2: si un navigateur Web est le moyen principal par lequel les utilisateurs accèdent à votre application Web, et si application / x-www-formulaire-urlencodée est le type de contenu ils publient, alors vous devriez 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 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 poster du contenu sur votre serveur. Je viens d’expliquer un peu différemment.]

Note 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 d'URI fonctionnant comme un moyen non hiérarchique de localiser une ressource.

Si les lecteurs de cette question souhaitent poser la question de savoir quelle est la bonne architecture RESTful: le modèle d'architecture RESTful n'exige pas que les schémas d'URI fonctionnent de 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 le fait de savoir si la capacité 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 précise, car les ressources sont localisées .)

Remarque finale: il arrive que les paramètres de requête soient utilisés pour d’autres tâches encore, qui ne sont ni la localisation de ressources, ni le contenu encodé. Avez-vous déjà vu un paramètre de requête tel que "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 paramètres soient considérés comme faisant partie de la chaîne de requête d'URL (sur le réseau), je soutiens qu'ils ne font pas partie de la requête de l'URL dans l'esprit .

Vous voulez des raisons? En voici un:

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

Source: norme HTML 4.01, section 17.13 Soumission de formulaire

Du point de vue de la programmation, pour le client, il regroupe les paramètres, les ajoute à l’URL et effectue un test POST et un test GET. Côté serveur, il évalue les paramètres entrants à partir de la chaîne de requête au lieu des octets publiés. Fondamentalement, c'est un lavage.

La façon dont des plates-formes clientes spécifiques fonctionnent avec des routines POST et GET dans leur pile réseau, ainsi que la manière dont le serveur Web traite ces demandes, pourraient présenter des avantages / des inconvénients. Selon votre implémentation, une approche peut être plus efficace que l'autre. Sachant que cela guiderait votre décision ici.

Néanmoins, du point de vue du programmeur, je préfère autoriser un POST avec tous les paramètres du corps ou un GET avec tous les paramètres de l'URL et ignorer explicitement les paramètres d'URL avec toute requête POST. Cela évite la confusion.

Je pense qu'il serait toujours assez RESTful de disposer d'arguments de requête identifiant la ressource sur l'URL tout en maintenant la charge de contenu limitée au corps de 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 contient des principes directeurs que nous pouvons utiliser pour normaliser la manière dont nous l'utilisons. Verbes HTTP. Ceci est utile lorsque vous construisez une API RESTful comme vous le faites.

En un mot: GET doit être en lecture seule, c’est-à-dire n’avoir aucun effet sur l’état du serveur. Le 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 l'action de votre 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 la réalisation de plusieurs POST est une mauvaise opération et la met en garde, car son objectif est de modifier l'état du serveur (par exemple, payer les marchandises à la caisse), et vous ne souhaitez probablement pas le faire deux fois. !

Comparez avec un GET que vous pouvez faire aussi souvent que vous le souhaitez (idempotent).

Je suis d'accord. Il est probablement plus prudent 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 le Concept POST + GET complet.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top