web-dev-qa-db-fra.com

REST - compromis entre la négociation de contenu via l'en-tête Accept et les extensions

Je travaille à la conception d'une API RESTful. Nous savons que nous voulons retourner JSON et XML pour une ressource donnée. J'avais pensé que nous ferions quelque chose comme ça:

GET /api/something?param1=value1
Accept:  application/xml (or application/json)

Cependant, quelqu'un a lancé des extensions pour cela, comme ceci:

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Quels sont les compromis avec ces approches? Est-il préférable de s'appuyer sur l'en-tête accept lorsqu'une extension n'est pas spécifiée, mais d'honorer les extensions lorsqu'elles sont spécifiées? Y a-t-il un inconvénient à cette approche?

40
Brandon Linton

Ceci, "Cependant, philosophiquement - la première approche est la seule approche.", Et ceci "L'approche officielle RESTful appropriée est d'utiliser Accept: header." sont largement perçus comme étant le cas, mais sont également absolument incorrects .

Voici un bref extrait de Roy Fielding (qui a défini REST) ​​...

"la section 6.2.1 ne dit pas que la négociation de contenu doit être utilisée tout le temps." citer

Cette conversation particulière se situe dans le contexte de l'en-tête "Accept-Language:", mais il en va de même pour l'en-tête "Accept:", comme cela est précisé plus loin dans sa réponse ...

"Je ne sais pas pourquoi les gens ne peuvent pas voir les deuxième et troisième liens sur la page d'accueil

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

qui pointent vers les deux éditions PDF. "

Ce qu'il veut dire, c'est qu'il n'y a aucun problème à utiliser différents points de terminaison pour différentes représentations des mêmes données source. (Dans ce cas, un point de terminaison .html et deux points de terminaison .pdf différents.)

Également dans une discussion similaire, cette fois concernant les vertus de l'utilisation des paramètres de requête par rapport à l'utilisation d'extensions de fichiers pour différents types de médias ...

"C'est pourquoi je préfère toujours les extensions. Aucun de ces choix n'a quoi que ce soit à voir avec REST." citer

Encore une fois, cela est légèrement différent des extensions Accepter vs nom de fichier, mais la position de Fielding est toujours claire.

Réponse - cela n'a vraiment pas beaucoup d'importance. Les compromis entre les deux ne sont pas très importants et les deux sont des styles acceptables.

38
Tom Christie

L'approche officielle RESTful appropriée consiste à utiliser Accept: entête.

Cependant, vous devez faire attention à ne pas casser la mise en cache, qui est l'une des exigences de REST. Vous devez avoir Vary: Accept en-tête et cache qui le comprend. Dans un monde idéal, vous l'auriez, mais dans la vraie vie, votre millage peut varier. La deuxième solution n'est donc pas aussi propre, mais elle pourrait être plus pratique.

Notez également que certains très anciens navigateurs ignoraient les en-têtes, s'appuyant plutôt sur l'extension.

10
vartec

Techniquement, cela n'a pas vraiment d'importance - votre serveur Web sera en mesure de passer le processus de manière appropriée à quoi il ressemble. (Je suppose cela mais ne ressemble pas à un showstopper).

Cependant, philosophiquement - la première approche est la seule approche. Dans REST, l'URL ne pointe en fait que vers un URI - qui n'est qu'une ressource. Pensez un instant à ceci ressource identique à objet dans la programmation orientée objet. Vous parlez à cette ressource via seulement 4 méthodes (aka GET/POST/PUT/DELETE -ou si tout ce que le transport permet) mais cette méthode ne devient pas description de l'objet . De même, les aspects de la valeur de retour ne sont pas l'URI. L'objet est toujours quelque chose et non quelque chose.xml ou quelque chose.json

Supposons que si vous ne voulez pas utiliser l'en-tête Accept, mais si vous voulez toujours être vraiment REST philosophiquement, je ne me dérangerai pas de quelque chose comme:

GET /api/something?parm1=value1&return_type=xml

par opposition à

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Mais comme je l'ai dit, cette différence n'est que philosophique.

9
Dipan Mehta

@vartec: Je pense que vous vous trompez

Le principe RESTful officiel approprié dit que rien ne doit être caché dans les en-têtes HTTP car c'est l'URI qui est exposé ou référencé, tout détail sur la demande/réponse doit être fourni dans le cadre de l'URI

Par conséquent, je recommande fortement d'éviter d'utiliser l'en-tête pour plus de détails sur la demande et la réponse, et de s'en tenir à

 GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Je ne suis pas en mesure de trouver rapidement les références, mais je posterai avec elles (en fait, vous pouvez vous référer au livre de publication d'O'reilly "RESTful web services" ( http://shop.oreilly.com/product/ 9780596529260.do ) qui confirme la même chose

0
Basav