Dans cet article, je vais présenter une nouvelle architecture de développement web, répondant au petit nom de XRX. Si le titre définit cette architecture par une opposition (au développement web actuel), c’est parceque je n’ai pas trouvé l’adjectif adéquat. Passionnante, exaltante, géniale cette architecture ? Surement, mais ça ne sonne pas bien. Pourtant, cette architecture simple et élégante comme la décrivent certains, révolutionne vraiment la manière actuelle de faire. En bien mieux.
Le développement web aujourd’hui
Ayant eu le malheur de me replonger il y a peu dans du développement web, j’ai eu l’occasion de me rendre compte en quoi il est absolument cassé et pénible.
Sur le client, on utilise le couple XHtml/CSS dont il faut reconnaître qu’il remplit correctement le rôle qui est le sien : structurer et présenter l’information. Seulement, ce n’est pas assez pour le développement d’applications. On ne peut pas blâmer XHtml pour ça, ça n’a jamais été son rôle. Le problème, c’est qu’on est quand même obligé de s’en servir !
C’est la que débarque la cavalerie : AJAX. AJAX, qui n’a rien de révolutionnaire, est le concept qui prône l’utilisation massive de Javascript et de l’objet XMLHttpRequest sur le client. Et en effet, avec des tonnes de Javascript il devient possible de créer des sites se rapprochant d’applications, moyennant des performances moyennes mais surtout une complexité effrayante même pour faire des choses basiques.
Regardons de plus prêt l’objet XMLHttpRequest. Si il a eu un tel succès, c’est parcequ’il permet de recharger une partie de la page sans recharger l’essemble de la page. Waouh. Je suis d’accord avec ceux qui me diront que ça permet d’économiser des resources, même si je ne suis pas sûr que ce soit vital dans la majorité des cas. Mais regardons les defauts de cette méthode : c’est d’une complexité incroyable ! Le scripts Javascript (avec ou sans AJAX d’ailleurs) sont imbuvables. N’espérez pas qu’ils soient facilement maintenables, c’est très difficile dès le moment où vous commencer à utiliser de l’AJAX. Si vous devez vous replonger dedans, ça sera la croix et la bannière pour comprendre le code. À la clef, une énorme perte de temps et des maux de têtes.
Voici comment on a perdu toute la simplicité et la légèreté du HTML.
En définitive, faire de l’AJAX, c’est refaire le travail du navigateur (envoyer la requête HTTP et traiter son retour) à la main. Pour une architecture moderne et bien pensée, on repassera. Si quelqu’un a déjà pris du plaisir à faire de l’AJAX, qu’il me fasse signe. Il apparait donc que cette technique est une béquille en attendant mieux. Comme le note Laurent Jouanneau, Ajax est déjà obsolète.
Une petite digression en passant. J’ai eu le malheur de devoir faire du Flex. Flex, pour ce qui ne connaissent pas, c’est le langage d’Adobe pour faire des applications web, choisi par beaucoup de responsables intoxiqués par la publicité d’Adobe (l’argument étant qu’ »on peut faire de jolies interfaces »). Quelle fut ma surprise quand j’ai réalisé que Flex se base sur de l’Ajax, en le simplifiant à peine. Ainsi, on doit toujours construire soit même ses requêtes HTTP, les envoyer et traiter le résultat de la requête. Même si le framework simplifie certains aspects de l’Ajax (on peut utiliser directement le XML résultant de la requête HTTP dans les composants de l’interface utilisateur), ça n’innove pas vraiment sur ce front. C’est pourquoi je suis plutôt sceptique sur l’avenir à long terme de ce langage. Si on peut éviter un web binaire et dirigé par une seule entreprise, tant mieux.
Cet aspect des choses n’est qu’une partie de ce qui constitue le développement web. Pour l’autre partie, ça se passe côté serveur.
Du côté du serveur, on utilise dans la majorité des cas un langage middleware, comme PHP, ASP ou Java et un système de gestion de base de données relationnelles (ici, chaque terme a son importance), dont le plus célèbre est sans doute MySQL.
Le rôle du middleware, prenons PHP par exemple, est la traduction. PHP récupère les différents paramètres issus de d’un requête HTTP (GET et POST dans la plupart des cas). Grâce à ces paramètres, on va former une requête SQL. Puis on exécute la requête. Si elle renvoie un résultat (SELECT), on le traite, et dans tous les cas, on recrache du code HTML qu’on renvoie au navigateur.
Le gros problème ne se situe pas du côté de PHP, mais du côté du système de gestion de base de données. Les bases de données qu’on utilise travaillent avec données tabulaires. Ça pose un énorme problème dans la mesure ou vos données ne sont quasiment jamais tabulaires. Et c’est là que commencent vos ennuis. Il faut plusieurs tables. Pour que vos données restent cohérentes, il faut utiliser des clefs étrangères afin de dire que telle cellule fait référence à une ligne d’une autre table. Ainsi, dès que la complexité de votre modèle de données augmente, il faut multiplier les tables et les contraintes qui vont avec. Mais en même temps, cela va complexifier vos requêtes. Vous aurez à multiplier les jointures externes. Et je ne parle même pas de l’insertion de données dans de telles structures, puisqu’il faut potentiellement ajouter des données dans plusieurs tables. Et si vous n’avez pas bien exprimé les contraintes entre les différentes tables, vous allez vite vous retrouver avec des données orphelines. Si le concept de bases de données épaisses essaye d’éviter cela, cela ne change rien au problème fondamental, qui est que ces multiples transformations apportent de la complexité et, potentiellement, des erreurs.
Sur le web, vos données ne sont pas tabulaires. Elles sont arborescentes.
L’architecture XRX
XRX tient pour XForms, Rest et XQuery.
Cette architecture simplifie le développement web dans le sens où on ne traite que du XML :
- XML sur le client ;
- XML sur le serveur ;
- des interfaces REST entre les deux.
Plus précisément, on utilise
- XForms sur le client,
- des interfaces REST et
- XQuery sur le serveur.
Grâce à cette architecture, plus besoin de transformer les données pour les faire tenir dans des structures tabulaires dans une base de données : toute la chaine utilise XML.
Sur le client, XForms
XForms est un langage conçu pour remplacer les formulaires web. Ils sont cependant très différents de ces derniers puisque ce langage s’appuie sur une architecture MVC (modèle, vue, contrôleur).
Ainsi, les données et les éléments de contrôle (bouton, champ de texte, liste déroulante, etc) ne sont pas mélangés.
Le modèle XForms contient à la fois les données récoltées (au format XML) et vouées à être envoyées au serveur, les contraintes qui s’exercent sur ces données (types, pertinence, donnée requise et autres contraintes) et les différentes manières dont elles peuvent être soumises. Les données peuvent être soumises directement en XML ou de manière plus classique avec les requêtes HTTP POST et GET habituelles.
Répétons-le : ces données et les contrôles sont complètement séparés.
Une des fonctionnalités clefs de XForms, c’est la vie après la soumission de ses données. En effet, on peut choisir d’afficher la nouvelle page, de ne rien faire, ou de remplacer tout ou partie du modèle XML par les données reçues en réponse. Il devient donc possible de recharger une partie de la page sans la recharger complètement. En un mot, faire de l’AJAX, à ceci près que c’est beaucoup plus simple puisqu’à la place de lourds scripts javascript, il n’y a besoin que de quelques éléments XForms.
Notons qu’il est aussi possible de précharger les données du modèle de manière à ce que le formulaire soit préremplit.
Au niveau des contrôles, on trouve tous ceux présent dans HTML, plus une commande d’étendue (<range/>) et une commande de sortie (<output/>) qui permet d’afficher une donnée du modèle XML. De plus, l’apparence des contrôles est intimement liée au type de la donnée auquel il est rattaché. Par exemple, si le contrôle est lié à une donné de type date, un calendrier s’affichera à la place d’un zone de texte. De même, si la donnée et de type booléen, c’est une case à cocher qui s’affichera. Les contrôles étant liés aux données, ils sont modifiés lorsque les données auxquelles ils sont rattachés sont modifiés. Ainsi, si plusieurs élément de contrôle sont liés à la même donnée, ils auront toujours le même état.
XForms gère aussi les structures répétitives. On peut donc construire des tableaux ou des listes à partir des données du modèle, insérer ou supprimer un élément, modifier les données d’une répétition, etc.
Les contrôleurs permettent d’établir des contraintes sur les données et les contrôles qui leurs sont associées. Ainsi, on peut définir le type d’une donnée conformément à XML Schéma, décider qu’une donnée est en lecture seule, requise, ou inutile (et dans ce dernier cas les contrôles qui sont liés à une telle données ne sont pas affichés) selon l’état d’autres données du modèle, on peut aussi calculer une valeur (par exemple une moyenne), et bien plus. On peut appliquer des styles CSS selon les différents cas. Par exemple, les contrôles en lecture seule peuvent avoir un fond grisé.
On peut également séparer le formulaire en différentes sections qui s’afficheront au fur et à mesure et à certaines conditions.
Enfin, il est possible de réagir à divers évènements (et toujours de façon déclarative, donc sans avoir recours à des scripts) : lorsque le chargement est terminé, lorsque les données sont sur le point d’être envoyées, lorsque les données sont en cours de soumission, lorsque les données sont reçues, lorsqu’on active un élément de contrôle, lorsqu’on insère ou supprime un élément dans une structure répétitive, lors de la sélection dans une liste, lorsqu’une erreur survient (ressource distante inexistante, erreur lors de la soumission, etc), etc. Il est en suite possible de répondre à ces évènements, en affichant un message d’erreur, en insérant ou en supprimant un élément dans une structure répétitive, en affectant une valeur à une donnée, en affectant le focus à un élément particulier, en affichant une partie précise du formulaire et ainsi de suite.
Tout ceci est possible sans écrire une seule ligne de javascript.
XForms utilise XPath, XML Schema et CSS tous les trois promus par le W3C.
Le principal défaut de XForms est qu’il n’est pas implémenté directement dans les navigateurs, et dans un avenir proche ce ne sera pas le cas, les développeurs privilégiant Webforms2, une évolution des formulaires Html. Malheureusement Webforms2 est conçu dans le but de ne pas casser la compatibilité et même s’il reprend certains concepts de XForms, il n’est pas assez puissant pour intégrer l’architecture XRX. Il faut donc se rabattre sur des bibliothèques capables de simuler XForms. Côté client, on pourra citer la bibliothèque javascript multi-navigateur Ubiquity Xforms qui semble le projet le plus prometteur à l’heure actuelle.
Sur le serveur, XQuery
L’essence de l’architecture XRX, c’est de n’avoir aucune transformations des données. Grâce à XForms, cela devient possible. En effet, les données d’un formulaire XForms sont au format XML. Il est en outre possible d’envoyer ces données directement en XML. Donc, côté serveur, il suffit de stocker ce fichier XML grâce à une base de donnée XML. Ainsi, les données ne sont pas transformées. Au contraire, elles sont rigoureusement les mêmes sur le client et sur le serveur.
On manipule les données d’une base de données XML grâce à XQuery. XQuery est le SQL du XML. Il est aussi puissant que SQL, mais permet de manipuler des données arborescente (XML) ce qui évidemment beaucoup plus puissant. XQuery est un langage fonctionnel sans effet de bord (qui ne modifie pas les données) mais des extensions standards intoduisent la mise à jour des données XML. XQuery n’est pas plus compliqué que SQL. Au contraire, étant donné qu’on utilise des structures arborescentes, les besoins en jointures se font plus rares.
Mais le mieux avec XQuery, c’est que ce langage renvoie directement du XML, et donc potentiellement du XHtml, du SVG et du XForms. Ainsi, une étape traditionnelle de transformation saute. Le résultat de la requête est directement renvoyée au navigateur dans des formats qu’il connait. En fait, XQuery est très intuitif et ne déroutera pas ceux qui ont déjà travaillé avec les bases de données traditionnelles.
XQuery peut aussi renvoyer des fichiers XML « bruts » à un formulaire XForms. Dans le cas où on veut remplacer AJAX, on renvoie seulement les donées nécessaires au formulaire XForms pour pouvoir continuer. Par exemple, lorsqu’on sélectionne une catégorie dans un formulaire XForms, celui-ci peut demander au serveur la liste des sous-catégories qui lui sera renvoyée en XML afin que le formulaire se mette à jour sans recharger toute la page.
Puisque vous semblez bruler d’envie de voir à quoi ressemble XQuery, voici une très brève introduction. Les requêtes XQuery sont constuires à partir d’expressions FLOWR, composées des instructions for, let, where, order by et result. L’instruction for permet de traiter une liste de nœuds. L’instruction let permet d’affecter une valeur à une variable qui, puisqu’on est dans un langage fonctionnel, n’est pas modifiable par la suite. L’instruction where permet de filtrer une liste de nœud, mais on peut aussi utiliser des prédicat. En plus, WHERE permet d’effectuer les jointures. La clause ORDER BY, comme sont nom l’indique, ordonne le résultat. Enfin, l’instruction RETURN renvoie un valeur ou un document XML.
Voici par exemple comment on renvoie une page XHtml simple à partir de données stockées dans une base de données XML :
<html> <head />
<body>
<h1>Liste des discussions</h1>
<ul>
{ for $discussion in document('discussions.xml')//discussion return
<li><a href="showDiscussion.xq?discussionsId={$discussion/@id}">{$discussion/titre}</a></li> }
</ul> }
</body>
</html>
avec un fichier discussion ayant un structure ressemblant à :
<discussions>
<discussion id="1">
<titre>Blabla</titre>
<texte>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam consequat nisi in risus volutpat nec sollicitudin justo pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque mi urna, dapibus et elementum et, tristique sit amet justo. Nulla convallis orci et eros condimentum fringilla. Suspendisse nec nisl felis, eu eleifend erat. Vivamus et urna nec nisi sollicitudin lacinia. Nullam ipsum purus, vehicula a faucibus eget, lobortis in justo. Aenean eget tempor nunc. Duis elit massa, rutrum a dignissim id, facilisis a leo. Proin felis est, cursus a ultrices eu, commodo ut ante.
</texte>
</discussion>
<discussion id="2">
<titre>Bla bla bla</titre>
<texte>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam consequat nisi in risus volutpat nec sollicitudin justo pharetra. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque mi urna, dapibus et elementum et, tristique sit amet justo. Nulla convallis orci et eros condimentum fringilla. Suspendisse nec nisl felis, eu eleifend erat. Vivamus et urna nec nisi sollicitudin lacinia. Nullam ipsum purus, vehicula a faucibus eget, lobortis in justo. Aenean eget tempor nunc. Duis elit massa, rutrum a dignissim id, facilisis a leo. Proin felis est, cursus a ultrices eu, commodo ut ante.
</texte>
</discussion>
</discussions>
Il est bien sûr possible de récupérer les paramètres et les données envoyés par la requête HTTP (GET, POST, PUT, DELETE). De même, rappelez vous qu’on peut renvoyer n’importe quel document XML, pas forcément une page XHtml.
XQuery, comme XForms, utilise le langage d’adressage XPath, très intuitif. XPath, en plus de pouvoir désigner certaines parties d’un document, peut effectuer des opérations sur les nombres, les chaînes de caractères, les dates et les nœuds XML. D’ailleurs, on peut souvent remplacer la clause WHERE par des prédicats XPath. XQuery utilise XPath2, plus puissant que sont prédécesseur XPath1.0. XForms2 utilisera aussi XPath2.
L’exemple précédent est simple, mais sachez qu’on peut imbriquer plusieurs niveaux de requêtes XQuery et donc produire des pages d’une complexité arbitraire.
Coté implémentation, c’est mieux que XForms. La majorité des bases de données importantes supportent la norme. En plus de cela, il existe une base de données XML libre, eXist. Elle gère très bien XQuery et apporte les extensions indispensables à l’architecture XRX. Ainsi on peut facilement récupérer les données issues de http, on peut utiliser un mécanisme d’authentification à la UNIX, on peut utiliser XInclude et Xslt, on peut utiliser WebDav et il y a même un module de traitement d’image. En prime, cette base de données XML semble à première vue plutôt performante (son créateur est très impliqué dans la norme XQuery) malgré qu’elle soit en Java (ce qui implique tout de même que eXist est portable). Ainsi, il devient possible de se passer complètement de langage tiers comme PHP ou ASP.
J’allais oublier : on peut aussi valider coté serveur les données reçues au format XML avec un schéma. On peut donc utiliser le même schéma XML sur le serveur et sur le client.
Entre les deux : des interfaces REST
La communication entre le navigateur et la base de données se fait via des interfaces REST, donc des URI.
Dans cette architecture, il est important de bien connaitre les subtilités d’HTTP. En effet, avec les bases de données XML, on utilise souvent des collections de documents XML stockés dans des dossiers. Grâce aux requêtes HTTP de type PUT et DELETE, il devient extrêmement facile de remplacer ou de supprimer un document XML faisant parti d’une collection, à condition de bien gérer les droits d’accès.
Ce qui devient intéressant, c’est qu’avec XRX on peut publier un service Web très facilement. En fait, chaque script XQuery devient un service Web.
Conclusion
XRX apporte ce qui manque au développement web : la simplicité. Quand on voit tous les framework qui sont nés et qui naissent encore des lacunes du développement web traditionnel, toutes ces usines à gaz, il est évident qu’il y a besoin de quelque chose de plus simple. XRX, en réduisant grandement la complexité et la quantité de code (division par 10 diront certains) des applications Web, répond à ce besoin.
Pour aller plus loin :