[Actualité] Halte au JSON et aux frameworks : vive les transformations XML pour les sites !
par
, 28/02/2018 à 14h32 (3148 Affichages)
N.B. Cet article est en partie un billet « d'humeur », destiné à provoquer le débat et n’est pas dénué de second degré et est donc réservé à ceux qui en disposent. Si par ailleurs vous connaissez déjà des déploiements pour le type d’orientation que je développe, merci de me l'indiquer en commentaire par un lien, ça m’intéresse. D’avance merci
–
Vous êtes à l’affût des dernières tendances de Vue.js ? Vous êtes incollable sur Angular ? Vous trouvez que vraiment, les applications XML c’est juste bon pour de vieux engins et quelques rares applications métier ? Le JSON est votre meilleur ami ?
À tort ! Les frameworks JavaScript c’est le mal – ou au moins l’utilisation bien souvent abusive des jQuery et autres ReactJS… Et le JSON – pardonnez-moi par avance si je heurte votre intelligence et vos pratiques – c’est gentil, mais c’est juste pour gérer quelques variables simples : un vrai jouet pour bambins.
—
Spoiler : j’en rajoute (beaucoup) dans mon introduction certes. Pour autant le propos de fond n’est pas éloigné de ma pensée et il y a parfois confusion entre les possibles et l’intérêt des outils entre eux.
Ainsi lorsque je vois un code avec du HTML « formaté » en JSON et dans l’attente d’être généré, je me dis que le monde est moche, vraiment. Car JSON est l’équivalent d’un dictionnaire : une paire clé/valeur. Pas d’attributs. Un manque, car vous devez passer du moins riche au plus riche en termes de données. Les astuces, avec l’utilisation de clés particulières renvoyant à des objets faisant office d’attributs, restent crades et peu pratiques (soyez de bonne foi !).
Alors pourquoi ne pas directement utiliser du XML dont hérite le HTML fut-il de version 4 ou 5... ? D’où vient cette manie de séparer la richesse du XML de nos si chères pages Web ? Une Web Application est-elle condamnée à (virtuellement) ne pas les utiliser ?!
Ne touche-t-on plutôt pas ici aux pratiques des développeurs, aux modes et à – peut-être – une forme de paresse, voire de méconnaissance de certains développeurs web qui ne jurent que par les plaquettes com’ de certaines firmes et écoles ? Je crois sincèrement l’heure venue d’avoir un débat, car, progressivement, les choses se décantent pour le web, son inusable JS et indirectement pour la pratique du XML sur le Web.
Tout d’abord un tour d’horizon de ce qu’apportent les Workers au doux et riche monde du XML, à l’heure où, pour le monde du Web mutualisé dans les grands opérateurs d’hébergement, le PHP devient ringard, dépassé et NodeJS toujours aussi instable… en nous demandant si parfois, l’orientation de pages disponibles hors ligne – base des applications Web – n’était pas la pierre qui manquait dans le mur du XML moderne.
Ce qui change tout : les Workers
Vous connaissez cette astuce qui prévoit de mettre du HTML dans une balise style au sein de votre body ? Une fois récupéré par le biais d’un querySelector, mais jamais pris en compte dans le HTML de la page, cela permet de faire des transformations locales (replace + parse) puis de réintégrer les éléments générés dans une page.
Plus propre qu’un display : none, la pratique séduit par sa relative réutilisation – pour la génération de listes complexes par exemple.
Pour autant le web se heurte à plusieurs inconnues/problématiques majeures qui dominent toujours les forums et nos pensées. En voici un résumé très personnel :
– la séparation données/présentation ou comment le JS s’est orienté vers MCV à défaut de pouvoir parfois continuer à générer des pages « toutes prêtes » et personnalisées côté serveur ;
– l’organisation de la page elle-même : représenter du HTML et sa richesse (attributs notamment) autrement que par du HTML, ce n’est pas si facile (et propre). Sauf si l’on utilise son parent le XML ;
– disposer d’un DOM facilement manipulable avant qu’il soit disponible et affiché par le navigateur, pour disposer des écouteurs d’événements ou faire des manipulations diverses et variées. Cela donnera, pour le cas de rafraîchissements très fréquents (et très bloquants pour l’usage de la page…), le cas des DOM virtuels. Des DOM virtuels qui doivent être plutôt détachés de l’exécution de la page elle-même, pour éviter d’être bloquants par effet de bord.
C’est là où intervient un nouveau venu : un travailleur JS. Corvéable à merci, il est un parfait esclave de nos exigences numériques (rien de répréhensible hein !).
Les Workers disposent de trois principales familles (voir ici et ici), héritées d’un même prototype d’objet et disponible par JavaScript. Tout d'abord un Web Worker de base (d’où le nom de Web Worker) simple et efficace, limité à la page qui l’appelle, qui dialogue avec elle et ne dispose pas d’accès au DOM du document. Pour du calcul bloquant, ou gérer certains appels, c’est parfait. C’est un « processus » à la sauce thread en Python par exemple.
Le Worker « au-dessus », c’est la même chose, mais il peut être partagé avec d’autres fenêtres/onglets : le Shared Worker. Une forme de multiprocessing dont les pipes sont limités en accès et qui répond toujours au domaine appelant (limitations CORS), et tourne en fond de tâche tant qu’il n’est pas tué ou qu’il reste au moins un onglet ouvert quelque part et qui fait appel à lui.
Enfin il y a le Service Worker, qui lui aussi répond à un domaine appelant (même s’il peut, sous condition et avec pas mal de restrictions, faire appel à des ressources hors des limites théoriques du CORS). La différence notable c’est qu’il ne tourne pas en fond de tâche : il est appelé pour un temps court (et sera tué s’il ne respecte pas certaines règles de bienséance numérique), pour « traiter » un lien appelé par une page. Il existe en dehors de l’existence des pages (sa création le rend indépendant des pages présentes et futures). Il a accès et lui seul, à un espace réservé qui est un cache local, pouvant charger moult fichiers en tout genre (CSS, JS, images, textes, HTML, JSON, XML, MP4, ZIP, que sais-je…). En interceptant les requêtes, il peut les modifier (un peu) et répondre par autre chose s’il le veut (souvent).
L’intérêt c’est qu’il peut servir de « préserveur » en stockant localement des fichiers. Ceux-ci peuvent être disponibles de lui seul (le fameux cache local) ou au travers d’IndexedDB (le pire truc que la terre ait jamais enfanté depuis le comportement effroyable de mon ex-voisine du haut). Il peut aussi servir du HTML généré… ou du XML…
Et si c’est trop lourd à transformer, un Shared Worker ou un Web Worker peuvent traiter des tâches pour lui…
Et une requête POST (sur une URL fantôme, interceptée, type /void) a un corps de requête qui peut contenir des données à mettre en cache pour resservir après…
Hum hum…
La trame que je propose (attention, étape aspirine)
De ces réflexions que je travaille ces deux dernières semaines, en voici le schéma général :
– réception de la requête par le serveur, en fonction de règles de redirection ;
– importation d’un premier XML, transformé par un XSL, produisant un code HTML5 valide → un cadre global adapté ;
– le navigateur exécute la page HTML produite et le JavaScript contenu inscrit un Service Worker qui procède dès que possible au téléchargement de tous les XSL disponibles en les intégrant dans une base locale, qui gérera par ailleurs les appels directs vers le serveur (le cache est une sorte préAPI de redirection) ;
– toute nouvelle ressource appelée par le biais d’un lien (renvoyant vers un XML) passera par le cache au travers du Shared Worker (SW) sans nouvel appel au serveur pour les XSL (étant déjà disponibles en cache). Ce ne sera donc pas directement la page qui procède à la transformation, mais un SW, qui communiquera le cas échéant au cache une ressource transformée à garder pour la suite (requête interceptée POST) ;
– les transformations par JavaScript permettent de ne pas avoir à rafraîchir toute une page, en modifiant à la volée certaines parties du HTML produit par la transformation. Soit le parcours suivant : appel de la page vers le SW => le SW fait une demande éventuelle auprès du cache => le cache vérifie s’il doit le télécharger => le SW fait éventuellement les transformations nécessaires de la réponse du cache et renvoie à la page le résultat => le JS de la page dispose d’un nouveau document – fragment – où piocher les éléments DOM à intégrer (remove simple ou par clone).
… Vous trouvez mon orientation, ma trame un poil compliquée ? Avez-vous déjà vu le fonctionnement théorique d’un DOM virtuel ? Le casse-tête des appels asynchrones que les Promises tendent de résoudre, des problématiques de portée de variables ? La sécurité des sessions pour des requêtes HTTP nécessairement stateless à l’heure où augmente le nombre de scripts extérieurs au site… ?
Si vous n’êtes toujours pas convaincu que cette solution n’est pas ni la pire ni la plus complexe au regard de toutes les autres (Churchill…) et répond à certaines problématiques bien actuelles, je vous conseille de lire rapidement la documentation d’implémentation du WebAssembly – particulièrement si vous n’avez jamais développé avec des langages de plus bas niveau… voilà ce qui vous attend.
Bref.
Dans la trame que je présente, le serveur distant pour la « lecture » seule des données se comporte comme un simple fournisseur de fichiers. Évidemment cela ne vaut pas dans deux cas non exclusifs l’un de l’autre :
– pour l’enregistrement des logs qui se fait également lors de l’appel des ressources indépendamment du logiciel de serveur (par exemple, avoir d’autres logs que seulement ceux d’Apache, Lighttpd, etc.) ;
– pour la vérification des droits d’accès au XSL/XML/… ou de certaines mises à jour (mon XML est-il à jour ?).
Un tel schéma d’échanges de XML/XSL est bien évidemment compatible côté serveur avec des bases NoSQL – particulièrement celles qui ont des orientations documents ou tous les systèmes distribués en règle générale –, mais plus surprenant (inusité ?), aussi avec certains systèmes SQL comme MariaDB qui supporte des colonnes au format texte/XML (au travers de fonctions disponibles telles que ExtractValue ou UpdateXML).
Quelques limitations cependant : si le site dispose de nombreux XSL ou que les données sont variées en structure, le cache localement peut être important, voire difficile à « résolver » (résoudre) totalement côté serveur. Cependant même pour des sites aussi « lourds » que peuvent être par exemple ceux des GAFA, la rationalisation des éléments affichés peut produire des portions de XSL faciles à maintenir et à intégrer dans une page (principe des gabarits/« template »).
Quand utiliser les uns ou les autres ?
Une conclusion en ouverture : quand savoir raisonnablement utiliser les différentes technologies utiles à votre projet et à vos ambitions ? Tout d’abord savoir où vous êtes à l’aise : le débogage, les vérifications de sécurité sont toujours plus simples, moins fastidieux, plus efficaces lorsque les outils utilisés sont connus. Le développement lui-même est plus aisé et rapide – ce qui réduit de manière non négligeable le coût.
Le schéma que je propose ici est particulièrement adapté lorsque le niveau d’exigence en termes de rafraîchissement reste raisonnable et que les transformations XSL sont correctement développées, comprises, gérables. De plus cela ne résout pas le problème de mise à jour « permanente » du contenu, des événements (scroll, etc.) comme du feed-back plus généralement : dans ce cas, l’utilisation de JS et des facilités offertes par les frameworks est particulièrement évidente et totalement indéniable. Bref pas le choix !
Pour un site « Internet » ou en intranet, qui se rapproche d’une utilisation type blog ou wiki, qui reste « relativement » statique, la « gabarisation » – car c’en est une – grâce à XML est probablement la meilleure approche (la moins coûteuse en termes de matériel, particulièrement si vous êtes sur des serveurs mutualisés où la ressource logicielle est rare). Idem si vous disposez déjà de ressources XML considérables (ouvrages, fichiers de configuration, de données, génération provenant des capteurs, etc.).
Reste qu’une telle méthodologie, approche, orientation – appelez cela comme vous le souhaitez – est compatible avec d’autres pratiques récentes comme les JSON Web Token (JWT), dont vous trouverez d’excellents exposés un peu partout –, et son orientation plus « tendance » et sécurisée (et disponible) que nos éternels cookies de session, qui obligent à un load balancer très efficace ou un cache de sessions distribué lorsque l’on dépasse un unique serveur.
Preuve que la modération et l’ouverture d’esprit dans le domaine technique comme dans d’autres, est souvent la meilleure manière d’être le plus efficient : XML+XSL représente, transforme et organise des données complexes ; le couple JS+JSON traite des variables, des appels et des requêtes désormais majoritairement de manière asynchrone.
Chacun chez soi et Linux pour tous.
Et vous ?
Qu'en pensez-vous ?