web-dev-qa-db-fra.com

URL reposantes avec des données dans la chaîne de requête ou le corps de la demande?

Quelle est la règle générale pour passer des données dans une URL REST dans la chaîne de requête par rapport au corps d'une demande?

Ie: Vous créez un service pour ajouter des joueurs de hockey. Vous pourriez aller avec:

PUT /players 
{ "name": Gretzky }

ou

PUT /players?name=Gretzky

Si vous transmettez beaucoup de données, vous devrez utiliser l'option n ° 1 car la longueur de l'URL est limitée. Mais à part cela, pourquoi ne pas simplement utiliser la chaîne de requête pour transmettre des données?


pdate: Suppression du commentaire que vous pouviez tester l'option # 2 dans un navigateur. Réalisé (duh) que vous ne pouvez faire que des GET dans votre navigateur.

33
Marcus Leon

Sur la base de la définition HTTP de PUT, votre première demande remplace la liste des joueurs par une nouvelle liste qui contient un seul nom de joueur. Il n'ajoute rien à la liste des joueurs.

La deuxième option n'a pas vraiment de sens pour moi. Faire PUT sans corps n'est pas vraiment cohérent avec le sens de PUT.

Étant donné que l'une des définitions standard de POST est d'ajouter à une ressource existante, je ne sais pas pourquoi vous ne feriez pas

POST /players 
{ "name": Gretzky }

Si vous êtes sûr que tous les noms de vos joueurs seront uniques, vous pouvez utiliser PUT comme ceci:

PUT /player/Gretzky
{ "name": Gretzky }

Lorsque vous décidez de faire REST sur HTTP, vous acceptez d'utiliser HTTP de la manière définie dans RFC2616. C'est ce que signifie la contrainte d'interface uniforme. Et juste pour être pédant, il n'y en a pas chose comme une URL REST et vous ne pouvez pas tester l'une ou l'autre option dans un navigateur car sans javascript, vous ne pouvez pas faire de PUT dans un navigateur.

31
Darrel Miller

L'option # 1 est très bien, mais probablement exagérée. L'option n ° 1 est pas correcte car elle n'est pas idempotente.

L'option n ° 2 est une [~ # ~] mauvaise [~ # ~] idée. Ce serait abuser de PUT. PUT doit être utilisé principalement lorsque la charge utile des données de votre demande est un bloc de données opaque, généralement volumineux ou hiérarchique. Les charges utiles plus petites et non hiérarchiques ont plus de sens en tant que POST.

Essayez également d'éviter de changer d'état via les paramètres de requête. Il n'y a rien de techniquement dangereux à cela si ce n'est pas une demande GET, mais ce n'est pas vraiment RESTful.

Dans ce cas, vous devez:

POST /players HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 12

name=Gretsky

Cela devrait renvoyer un 201 Created réponse. (Il existe une exception à cette règle: si vous ne créez pas la ressource immédiatement et qu'elle peut être rejetée ultérieurement, utilisez 202 Accepted au lieu.)

Écrire un REST service Web qui utilise plus de HTTP que POST et GET ne doit être fait que après après avoir lu le - Spécification HTTP . (C'est une très lecture utile.) Cette règle est un peu plus souple si vous utilisez un framework qui prend toutes les décisions pour vous.

3
Bob Aman

Ma compréhension des opérations REST est que l'URL identifie de manière unique la ressource, tandis que le corps de la demande contient la représentation de la ressource. Étant donné que, il est douteux que l'une de vos options soit vraiment RESTful.

Le premier serait, en supposant que la ressource est nommée "Players" et qu'un GET sur cette ressource retourne une liste de joueurs (je n'entrerai pas dans la question de savoir si ce GET retourne d'autres URL de ressource ou non ... Fielding dirait qu'il le devrait, avec des demandes individuelles pour obtenir les données sur les ressources).

La seconde serait, en supposant que le corps de la demande contenait des informations saisies par le nom "Gretsky". Cependant, cela vous oblige à générer les clés en externe.

2
kdgregory