web-dev-qa-db-fra.com

Qu'est-ce qui ne va pas avec un point de terminaison renvoyant du HTML plutôt que des données JSON?

Quand j'ai commencé à apprendre PHP (il y a environ 5 ou 6 ans), j'ai appris Ajax , et je suis passé par "les phases":

  1. Votre serveur renvoie des données HTML et vous les mettez dans un DOM's innerHTML
  2. Vous en apprendrez plus sur les formats de transfert de données tels que XML (et dites "oooh donc c'est à ça qu'il sert), puis sur JSON.
  3. Vous retournez JSON et créez votre interface utilisateur en utilisant du code JavaScript Vanilla
  4. Vous passez à jQuery
  5. Vous en apprendrez plus sur les API, les en-têtes, les codes d'état HTTP, RESTE , CORS et - Bootstrap
  6. Vous apprenez SPA , et les frameworks frontend ( React , Vue.js , et AngularJS ) et la norme API JSON.
  7. Vous recevez un code hérité d'entreprise et en l'inspectant, constatez qu'ils font ce qui est décrit à l'étape 1.

Comme je travaillais avec cette base de code héritée, je ne pensais même pas qu'elle pouvait retourner du HTML (je veux dire, nous sommes des professionnels maintenant, non?), Donc j'ai eu du mal à rechercher le point de terminaison JSON qui renvoyait les données qui les appels Ajax peuplent. Ce n'est que lorsque j'ai demandé au "programmeur" qu'il m'a dit qu'il renvoyait du HTML et qu'il était ajouté directement au DOM avec innerHTML.

Bien sûr, c'était difficile à accepter. J'ai commencé à réfléchir à des moyens de refactoriser cela en points de terminaison JSON, en pensant à l'unité de test des points de terminaison, etc. Cependant, cette base de code n'a aucun test. Pas un seul. Et c'est plus de 200k lignes. Bien sûr, l'une de mes tâches consiste à proposer des approches pour tester le tout, mais pour le moment nous ne nous attaquons pas encore à cela.

Je ne me demande donc nulle part, dans un coin: si nous n'avons aucun test, nous n'avons donc aucune raison particulière de créer ce point de terminaison JSON (car il n'est pas "réutilisable": il renvoie littéralement des données qui ne tiennent que sur cette partie de la application, mais je pense que cela était déjà implicite car il ... renvoie des données HTML).

Qu'est-ce exactement qui ne va pas avec cela?

79

Qu'est-ce qui ne va pas avec un point de terminaison renvoyant du HTML plutôt que des données JSON?

Rien, vraiment. Chaque application a des exigences différentes, et il se peut que votre application n'ait pas été conçue pour être un SPA.

Il se peut que ces magnifiques frameworks que vous avez cités (Angular, Vue, React, etc ...) n'étaient pas disponibles au moment du développement, ou n'étaient pas des trucs d'entreprise "approuvés" à utiliser dans votre organisation.

Je vais vous dire ceci: un point de terminaison qui renvoie du HTML réduit votre dépendance aux bibliothèques JavaScript et réduit la charge sur le navigateur de l'utilisateur car il n'aura pas besoin d'interpréter/exécuter du code JS pour créer des objets DOM - le HTML est déjà là, il s'agit simplement d'analyser les éléments et de les rendre. Bien sûr, cela signifie que nous parlons d'une quantité raisonnable de données. 10 mégaoctets de données HTML ne sont pas raisonnables.

Mais comme il n'y a rien de mal à retourner du HTML, ce que vous perdez en n'utilisant pas JSON/XML, c'est essentiellement la possibilité d'utiliser votre point de terminaison comme API. Et là se trouve la plus grande question: faut-il vraiment que ce soit une API?

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

115
Machado

JSON et HTML remplissent deux objectifs sémantiques différents.

Si vous remplissez une page Web avec des données, utilisez JSON. Si vous créez une page Web à partir de parties de pages Web, utilisez HTML.

Ils peuvent sembler un peu comme s'ils étaient la même chose, mais ils ne le sont pas du tout. D'une part, lorsque vous créez une partie d'une page Web à l'aide du code HTML renvoyé par le serveur, vous travaillez côté serveur. Lorsque vous liez des données à une page Web, vous travaillez - côté client.

En outre, vous devez être prudent avec HTML pour ne pas lier étroitement à une page spécifique. L'intérêt de rendre les pages partielles de cette manière est que les partiels soient réutilisables et si vous rendez le partiel trop spécifique, il ne sera pas composé sur d'autres pages. JSON n'a pas ce problème, car ce ne sont que des données, pas la structure d'une page Web.

50
Robert Harvey

Le principal problème est qu'il couple étroitement le serveur au client, qui doit connaître la structure HTML. Cela rend également les points finaux plus difficiles à réutiliser de nouvelles façons ou de nouvelles applications.

Renvoyer des données simples et laisser le client le rendre diminue le couplage et augmente la flexibilité et la testabilité - vous pouvez exécuter des tests unitaires sur le client pour les données factices et exécuter des tests unitaires sur le serveur pour tester les données souhaitées.

22
DeadMG

Je pense que vous l'avez un peu en arrière. Vous dites:

nous n'avons aucun test, nous n'avons donc aucune raison particulière de créer ce point de terminaison JSON

Une raison d'utiliser un point de terminaison approprié serait que vous pourriez le tester. Je dirais que l'absence de tests est une très bonne raison de commencer à en écrire. Autrement dit, s'il existe une logique qui pourrait être testée.

200k lignes de code sont beaucoup à refactoriser et sont probablement difficiles à maintenir. Décomposer certains points de terminaison et les tester peut être un bon point de départ.

Une autre raison pourrait être de séparer le serveur du client. Si, dans un avenir lointain, la conception ou la mise en page de l'application change, il est plus facile de travailler avec un format de données approprié que la sortie HTML. Dans un monde idéal, il vous suffirait de changer de client et de ne pas toucher du tout au serveur.

14
Victor Sand

Il existe 3 façons (au moins?) De créer une page Web:

  • Générez la totalité du côté serveur de pages.
  • Renvoyez une page simple du serveur et du code (JavaScript), et demandez à la page de récupérer ses données et de les rendre dans le côté client HTML.
  • Renvoyez une page partielle et du code, et demandez au code de récupérer des blocs HTML pré-rendus qu'il peut déposer dans la page.

Le premier est très bien. Le second est également très bien. C'est le dernier qui pose problème.

La raison est simple: vous avez maintenant divisé la construction de la page HTML en parties complètement déconnectées. Le problème est un problème de maintenance. Maintenant, vous avez deux séparées entités chargées de gérer les détails de l'interface utilisateur. Vous devez donc garder le CSS et d'autres détails similaires synchronisés entre les deux pièces distinctes. Vous avez changé la largeur de la barre latérale? Génial. Maintenant, le fragment HTML qui revient provoque un défilement horizontal car ses hypothèses sur la largeur de la barre latérale ne tiennent plus. Vous avez changé la couleur d'arrière-plan de ce bloc? Génial, maintenant la couleur de la police de votre fragment HTML s'oppose car il supposait une couleur d'arrière-plan différente et quelqu'un a oublié de tester ce point de terminaison.

Le fait est que vous avez maintenant divisé les connaissances qui devraient être centralisées en un seul endroit (à savoir la logique de présentation), ce qui rend plus difficile de s'assurer que toutes les pièces s'emboîtent correctement. En utilisant une API JSON, vous pouvez à la place conserver toute cette logique dans le frontal uniquement, ou vous pouvez tout conserver dans vos modèles côté serveur si vous restituez vos données en HTML pour commencer. Il s'agit de conserver les connaissances/la logique de présentation en un seul endroit, afin qu'elles puissent être gérées de manière cohérente et dans le cadre d'un processus unique. HTML/CSS/JS est assez difficile à garder droit sans le décomposer en beaucoup de petits morceaux.

Les API JSON ont également l'avantage supplémentaire de rendre les données disponibles complètement indépendamment de la logique de présentation. Cela permet à plusieurs présentateurs différents, tels qu'une application mobile et une page Web, de consommer les mêmes données. En particulier, il permet de consommer les données sans navigateur (comme les applications mobiles ou les tâches cron nocturnes); ces consommateurs peuvent même ne pas être en mesure d'analyser le HTML. (Bien entendu, cela repose nécessairement sur une situation dans laquelle les données sont les mêmes entre les différents consommateurs, ou l'un peut utiliser un sous-ensemble de l'autre.) Cependant, si vous avez besoin de cette capacité dépend des exigences de votre application particulière, tout en gérant votre présentation la logique est nécessaire malgré tout. Je dirai cependant que si vous le mettez en œuvre dès le départ, vous serez mieux préparé pour la croissance future.

6
jpmc26

Je dirais qu'il n'y a rien de mal à ce que le serveur renvoie un fragment HTML et que l'interface utilisateur l'assigne à .innerHTML d'un élément. C'est, à mon avis, le moyen le plus simple de développer du code JavaScript asynchrone. L'avantage est que le moins possible est fait en utilisant JavaScript et autant que possible dans un environnement back-end contrôlé. N'oubliez pas que la prise en charge de JavaScript dans les navigateurs varie, mais votre back-end a toujours la même version des composants back-end, ce qui signifie que faire autant que possible dans le back-end signifie aussi peu d'incompatibilités de version que possible.

Maintenant, parfois, vous voulez plus qu'un simple fragment HTML. Par exemple, un code d'état et un fragment HTML. Ensuite, vous pouvez utiliser un objet JSON qui a deux membres, statusCode et HTML dont le second peut être affecté à .innerHTML d'un élément après avoir vérifié le statusCode. Ainsi, l'utilisation de JSON et l'utilisation de innerHTML ne sont en aucun cas des approches exclusives alternatives; ils peuvent être utilisés ensemble.

En utilisant JSON, vous pouvez même avoir plusieurs fragments HTML dans la même réponse qui sont affectés au .innerHTML de plusieurs éléments.

En résumé: utilisez .innerHTML. Il rend votre code compatible avec autant de versions de navigateur que possible. Si vous avez besoin de plus, utilisez JSON et .innerHTML ensemble. Évitez XML.

4
juhist

Il n'y a rien de mal en principe. La question est: que voulez-vous réaliser?

JSON est parfait pour transmettre des données. Si vous envoyez du HTML à la place et attendez du client qu'il extrait les données du HTML, ce sont des déchets.

D'autre part, si vous voulez pour transmettre HMTL qui va être rendu en HTML, puis envoyez-le en HTML - au lieu de compresser le HTML dans une chaîne, de transformer la chaîne en JSON, de transmettre JSON , le décoder de l'autre côté, obtenir une chaîne et extraire le code HTML de la chaîne.

Et hier, je suis tombé sur du code qui a mis deux éléments dans un tableau, transformé le tableau en JSON, mis le JSON dans une chaîne, mis la chaîne à l'intérieur d'un tableau, transformé le tableau entier en JSON, envoyé au client, qui a décodé le JSON, a obtenu un tableau contenant une chaîne, a pris la chaîne, a extrait le JSON de la chaîne, a décodé le JSON et a obtenu un tableau avec deux éléments. Ne fais pas ça.

4
gnasher729

Tout cela dépend du but de l'API, mais généralement ce que vous décrivez est une violation assez forte de séparation des préoccupations:

Dans une application moderne, le code API doit être responsable des données et le code client doit être responsable de la présentation.

Lorsque votre API renvoie du HTML, vous couplez étroitement vos données et votre présentation. Lorsque l'API renvoie du HTML, la seule chose que vous pouvez faire (facilement) avec ce HTML est de l'afficher comme faisant partie d'une page plus grande. Sous un angle différent, la seule chose pour laquelle l'API est bonne est de fournir du HTML à votre page. De plus, vous avez réparti votre code HTML sur le code client et serveur. Cela peut faire de l'entretien un casse-tête.

Si votre API renvoie JSON, ou une autre forme de données pures, cela devient beaucoup plus utile. L'application existante peut toujours consommer ces données et les présenter de manière appropriée. Maintenant, cependant, d'autres choses peuvent utiliser l'API pour accéder aux mêmes données. Encore une fois, la maintenance est plus facile - tout le code HTML réside en un seul endroit, donc si vous souhaitez remodeler l'ensemble du site, vous n'avez pas besoin de changer votre API.

3
SouthShoreAK

Le HTML est lié à une conception et une utilisation spécifiques.

Avec HTML, si vous voulez changer la mise en page, vous devez changer la façon dont le html est généré par l'appel du serveur. Habituellement, cela nécessite un programmeur principal. Vous avez maintenant des programmeurs principaux, qui par définition ne sont pas vos meilleurs rédacteurs html, qui gèrent ces mises à jour.

Avec JSON, si la mise en page change, l'appel au serveur JSON existant ne doit pas nécessairement changer du tout. Au lieu de cela, votre développeur frontal, ou même le concepteur, met à jour le modèle pour produire le HTML différent que vous souhaitez à partir des mêmes données de base.

De plus, le JSON peut devenir la base d'autres services. Vous pouvez avoir différents rôles qui doivent voir les mêmes données de base de différentes manières. Par exemple, vous pouvez avoir un site Web client qui affiche des données sur un produit dans une page de commande, et une page de vente interne pour les représentants qui affiche les mêmes données dans une mise en page très différente, peut-être à côté d'autres informations non disponibles pour les clients généraux. Avec JSON, le même appel serveur peut être utilisé dans les deux vues.

Enfin, JSON peut mieux évoluer. Ces dernières années, nous avons en quelque sorte dépassé les cadres javascript côté client. Je pense qu'il est temps de prendre du recul et de commencer à réfléchir au javascript que nous utilisons et à la façon dont il affecte les performances du navigateur ... en particulier sur les appareils mobiles. Cela dit, si vous exécutez un site suffisamment grand pour nécessiter une batterie de serveurs ou un cluster, au lieu d'un seul serveur, JSON peut mieux évoluer. Les utilisateurs vous donneront du temps de traitement dans leurs navigateurs gratuitement, et si vous en profitez, vous pouvez réduire la charge du serveur dans un grand déploiement. JSON utilise également moins de bande passante, donc encore une fois, si vous êtes assez grand et utilisez-le de manière appropriée, JSON est nettement moins cher. Bien sûr, cela peut également s'aggraver, si vous finissez par alimenter des bibliothèques de 40 Ko pour analyser 2 Ko de données en 7 Ko de code HTML, encore une fois: cela vaut la peine d'être conscient de ce que vous faites. Mais le potentiel est là pour que JSON améliore les performances et les coûts.

2
Joel Coehoorn

Il n'y a rien de mal à un tel point final s'il remplit ses exigences. S'il est nécessaire de cracher du HTML qu'un consommateur connu peut analyser efficacement, pourquoi pas?

Le problème est que, dans le cas général, vous voulez que vos points de terminaison crachent une charge utile bien formée et efficacement analysable par un analyseur standard. Et par effectivement analysable, je veux dire, analysable de façon déclarative.

Si votre client est obligé de lire la charge utile et d'en extraire les bits d'information ouverts avec des boucles et des instructions if, il n'est pas effectivement analysable. Et HTML, étant la façon dont il est, il est très pardonné de ne pas exiger d'être bien formé.

Maintenant, si vous vous assurez que votre html est conforme au xml, alors vous êtes en or.

Cela dit, j'ai un problème important avec ceci:

Je vais vous dire ceci: un point de terminaison qui renvoie du HTML réduit votre dépendance aux bibliothèques JavaScript et réduit la charge sur le navigateur de l'utilisateur car il n'aura pas besoin d'interpréter/exécuter du code JS pour créer des objets DOM - le HTML est déjà là, il s'agit simplement d'analyser les éléments et de les rendre. Bien sûr, cela signifie que nous parlons d'une quantité raisonnable de données. 10 mégaoctets de données HTML ne sont pas raisonnables.

C'est une mauvaise idée, peu importe comment vous le coupez. Des décennies d'expérience industrielle collective nous ont montré qu'en général, il est judicieux de séparer les données (ou le modèle) de leur affichage (ou vue).

Ici, vous combinez les deux afin d'exécuter rapidement du code JS. Et c'est une micro optimisation.

Je n'ai jamais vu cela comme une bonne idée, sauf dans des systèmes très triviaux.

Mon conseil? Ne le fais pas. DRACONES HC SVNT , YMMV, etc.

1
luis.espinal

Il est difficile de classer un bien ou un mal. OMI, les questions que je vais poser sont: "devrait-il", ou "peut-il faire avec moins?".

Chaque point de terminaison doit s'efforcer de communiquer avec le moins de contenu possible. Le rapport signal/bruit est généralement des codes HTTP <JSON <XHTML. Dans la plupart des situations, il est bon de choisir le protocole le moins bruyant.

Je diffère sur le point concernant la charge du navigateur client par @machado, car avec les navigateurs modernes, ce n'est pas un problème. La plupart d'entre eux sont assez bien équipés pour gérer les codes HTTP et les réponses JSON. Et bien que vous n'ayez pas de tests pour le moment, la maintenance à long terme d'un protocole moins bruyant serait moins chère que celle qui le précède.

0
hazardous

JSON n'est qu'une présentation textuelle de données structurées. Un client doit naturellement avoir un analyseur pour traiter les données, mais pratiquement toutes les langues ont des fonctions d'analyseur JSON. Il est beaucoup plus efficace d'utiliser l'analyseur JSON que d'utiliser l'analyseur HTML. Cela prend peu d'empreinte. Ce n'est pas le cas avec un analyseur HTML.

En PHP, vous utilisez simplement json_encode($data) et c'est au client de l'autre côté de l'analyser. Et lorsque vous récupérez des données JSON à partir d'un service Web, vous utilisez simplement $data=json_decode($response) et vous pouvez décider comment utiliser les données comme vous le feriez avec des variables.

Supposons que vous développiez une application pour un appareil mobile, pourquoi avez-vous besoin du format HTML alors que les applications mobiles utilisent rarement le navigateur Web pour analyser les données? De nombreuses applications mobiles utilisent JSON (format le plus courant) pour échanger des données.

Étant donné que les mobiles sont souvent sur des plans avec compteur, pourquoi voulez-vous utiliser du HTML qui prend beaucoup plus de bande passante que JSON?

Pourquoi utiliser HMTL alors que HTML est limité dans son vocabulaire et que JSON peut définir des données? {"person_name":"Jeff Doe"} est plus informatif que HTML ne peut fournir sur ses données car il définit uniquement la structure des analyseurs HTML, pas les données.

JSON n'a rien à voir avec HTTP. Vous pouvez mettre JSON dans un fichier. Vous pouvez l'utiliser pour des configurations. Composer utilise JSON. Vous pouvez également l'utiliser pour enregistrer des variables simples dans des fichiers.

0
netrox