web-dev-qa-db-fra.com

Est-il correct de retourner du HTML à partir d'une API JSON?

Dans mon projet actuel, je suis responsable de la mise en œuvre d'un service qui implique la consommation d'API RESTful nouvellement créées, documentées comme prenant uniquement en charge JSON.

Le client fait régulièrement des demandes avec l'en-tête d'acceptation de "application/json" et le type de contenu de "application/json". Cependant, certains points de terminaison envoient une réponse avec un type de contenu HTML, même un corps HTML. Pour moi, c'est clairement la mauvaise approche et ne peut jamais être justifiée.

Tout au long du projet, cette même pratique a été appliquée à deux fournisseurs différents et à deux services différents. Je me suis retrouvé à devoir justifier pourquoi les services devaient être modifiés. Les fournisseurs ont déclaré que le client devrait faire face à cela et même ma bibliothèque REST de choix a été remise en question (RestEasy) car il ne fait pas face à cela par défaut 'out the box'.

Cela a été un point de frustration majeur. Je ne trouve pas beaucoup de références pour étayer mon argument, je suppose que c'est parce que le point est théorique, car il est si évident.

La question est, est-ce que je manque quelque chose? suis-je pédant à ce sujet? Est-il correct d'avoir une API JSON qui n'a pas de type de contenu d'application/json dans ce scénario? Des références seraient appréciées. Comment résolvez-vous cette situation d'un point de vue commercial?

25
phillip.darley

Lorsque vous envoyez un en-tête accept demandant un type de média spécifique, le serveur ne doit pas renvoyer autre chose, et certainement pas avec un code d'état 200 OK

De Restpatterns.org :

Si aucun champ d'en-tête Accept n'est présent, il est supposé que le client accepte tous les types de supports. Si un champ d'en-tête Accept est présent, et si le serveur ne peut pas envoyer une réponse acceptable selon la valeur combinée du champ Accept, alors le serveur DEVRAIT envoyer une réponse 406 (non acceptable).

(Souligner le mien)

Restpatterns.org prend cela à partir de la norme HTTP réelle: Définitions des champs d'en-tête - Accepter

En bref: vous n'êtes pas pédant. Les services ne suivent pas la norme HTTP s'ils renvoient du HTML lorsque l'en-tête accept leur dit spécifiquement de retourner application/json et rien d'autre.

28
Marjan Venema

Que voulez-vous dire par "API JSON RESTful" - Je pense que le premier problème ici est que vous mélangez des concepts (ou peut-être quelqu'un entre vous et vos homologues techniques chez vos "fournisseurs").

Une API RESTful (que vous ne parliez pas du tout vraiment au niveau 1 ou quelque chose au niveau 3 ou supérieur cf http://martinfowler.com/articles/richardsonMaturityModel.html ) est sur le chemin vous interagissez avec l'API et non au sujet du format du contenu envoyé ou reçu. Il ne s'agit même pas de protocoles ou de mécanismes de transport ...

De même, une API JSON est une API qui prend en charge l'utilisation de JSON en tant que format de données - elle peut ou non être reposante, elle peut ou non être implémentée en utilisant HTTP et (et c'est le point clé) elle peut ou peut-être pas supporte exclusivement JSON.

Une bonne API exécutée sur HTTP (il est raisonnable de supposer que dans le contexte vous parlez d'une API exposée sur HTTP) devrait vous permettre de demander du contenu dans une variété de formats et ces formats peuvent (et devraient probablement) inclure HTML ainsi que JSON et XML. Pourquoi? Eh bien, cela rendrait l'apprentissage de l'API beaucoup plus facile, conceptuellement, il fournit une UX basée sur un navigateur instantané pour n'importe quel but et ainsi de suite ...

La question intéressante devient alors si mon API, qui prend en charge une variété de formats de contenu, est appelée sans qu'on lui dise quel format le client attend alors quel format doit-elle retourner ...? Cela tend vers un argument religieux - mais HTML donne au fournisseur la possibilité d'inclure des informations utiles (comme "n'oubliez pas de définir l'en-tête accepter le contenu").

Pour répondre à la question, une API, qui est reposante et qui prend en charge json, doit absolument pouvoir retourner du HTML si c'est le contenu demandé.

9
Murph

Le client fait régulièrement des demandes avec l'en-tête d'acceptation "application/json" et le type de contenu "application/json"

Oui, c'est la bonne chose à faire, mais cela ne signifie pas que le vendeur s'en soucie. Bien que je comprenne totalement votre frustration, car je pense également qu'un service JSON devrait toujours donner une réponse JSON, mais il existe de nombreux exemples où ce n'est pas le cas.

Tout au long du projet, cette même pratique a été appliquée à deux fournisseurs différents et à deux services différents. Je me suis retrouvé à devoir justifier pourquoi les services devaient être modifiés. Les fournisseurs ont déclaré que le client devrait faire face à cela et même ma bibliothèque REST de choix a été remise en question (RestEasy) car il ne fait pas face à cela par défaut 'out the box'.

Eh bien, je dois être d'accord avec le vendeur. C'est leur service et tant qu'ils documentent clairement les cas particuliers d'utilisation, vous ne pouvez pas vraiment leur imposer de le changer. C'est un inconvénient pour eux, car les développeurs seront lents à adopter leur API, et s'ils écoutaient ce dont les développeurs ont besoin, ils le changeraient, mais malheureusement, il n'y a pas de règle selon laquelle ils doivent suivre les normes.

La question est-ce que je manque quelque chose?

Les en-têtes de demande ne signifient rien sauf s'ils sont correctement interrompus à l'autre extrémité. Je sais que si je développe une API web en utilisant PHP, alors au diable les en-têtes de requête. Je peux répondre avec tout ce que je veux. Alors qu'un service configuré en IIS avec C # offre une gestion beaucoup plus facile des en-têtes de demande, de leur type et du type de réponse. Cela a beaucoup à voir avec les outils utilisés par le fournisseur pour créer l'API. .

Je suis pédant à ce sujet?

Oui et non. J'ai des amis développeurs qui ne pourraient pas passer outre. Ils deviendraient tellement obsédés par le problème et incapables de poursuivre d'autres tâches jusqu'à ce que l'API fonctionne comme ils l'attendent. Maintenant c'est pédant.

C'est un problème car le fournisseur a créé "plus de travail" pour terminer vos tâches. N'importe qui serait frustré par cela. Je sais que je le serais.

Est-il correct d'avoir une API JSON qui n'a pas de type de contenu d'application/json dans ce scénario?

Absolument, mais ce n'est pas une bonne pratique.

Un client ne peut dire au serveur que le type de contexte d'un request. Il n'a pas la possibilité d'appliquer un type de contenu pour le response. Le client peut seulement informer le serveur qu'il va accept une collection de types de contenu possibles.

Définitions des champs d'en-tête

Le champ En-tête de demande d'acceptation peut être utilisé pour spécifier certains types de supports acceptables pour la réponse. Accepter les en-têtes peut être utilisé pour indiquer que la demande est spécifiquement limitée à un petit ensemble de types souhaités, comme dans le cas d'une demande d'image en ligne.

Il est possible pour un client de demander une image de image/jpeg, mais le serveur répond avec text/html et un code d'état de 404 si l'image est introuvable. Les serveurs peuvent également répondre incorrectement. Il existe de nombreux sites Web Wordpress qui répondent par text/html et code d'état 200 pour les pages de fichiers non trouvés.

Maintenant, c'est tout [~ # ~] mauvais [~ # ~] pratique de la part du serveur. Ce que j'essaie de vous dire, c'est que c'est absolument possible, et ça arrive souvent. Les gens ne savent pas ce qu'ils font lorsqu'ils configurent ces choses.

Des références seraient appréciées. Comment résolvez-vous cette situation d'un point de vue commercial?

J'ai rencontré ce problème sur quelques projets. Vous post les données JSON au serveur et il renvoie soit une réponse JSON ou HTML.

Ce n'est vraiment pas un gros problème de savoir quel type était dans la réponse. Si le premier caractère est { ou [ vous pouvez assumer JSON. Si c'est < vous pouvez assumer HTML. Voilà comment je l'ai géré dans le passé. Parfois, le programmeur qui a écrit l'API sait tout sur les en-têtes HTTP. Tout revient comme text/html réponses. Si vous avez de la chance, Apache est configuré par défaut sur text/plain ce qui peut parfois aider.

Ces problèmes existent et continueront d'exister dans le futur. La communication de serveur à serveur est de loin une activité non réglementée. Il n'y a pas d'organe directeur qui expulsera un fournisseur d'une union pour un serveur qui donne de mauvaises réponses HTTP.

5
Reactgular