Sujet un peu vaste que j'aborde ici, mais qui me semble fondamental tant pour assurer une bonne structure applicative web que pour sa maintenabilité dans le temps. J'ai vu en effet trop de code de sites ou d'applications web, dans lesquels la bonne organisation et structuration de leur code dans un contexte de gestion d'appels Ajax, était vraiment absente. Ce que je trouve assez regrettable.
Aujourd'hui, l'Ajax est une technologie incontournable dans les applications web pour plusieurs raisons dont voici à mon sens les principales :
- la qualité de l'expérience utilisateur ;
- une meilleure segmentation et répartition de charge applicative sur le réseau ;
- la gestion des caches client et serveur optimisée, plus fine et plus efficace.
Avant d'entrer dans le vif du sujet, je tiens à préciser que je ne vais pas parler dans ce billet du côté client et donc de la partie JavaScript de la gestion Ajax. Ce n'est pas l'objet de ce billet d'une part, et, d'autre part, j'estime qu'une telle structuration de code et d'optimisation est étroitement dépendante de l'architecture et des technologies spécifiques choisies et utilisées pour une application web côté client. Je dirai également pour finir, que malgré cette diversité de choix possibles côté client, tant au niveau architecture logicielle que de la structure et gestion des divers processus à ce niveau, il reste possible de définir des "constantes" de gestion qui peuvent se standardiser quel que soit le contexte. J'aurais l'occasion d'y revenir plus en détail dans un autre billet.
1) Pourquoi est-il important de structurer son code côté serveur dans un contexte Ajax ?
Sans vouloir jouer les rabats-joie, et revenir sur les fondements de la programmation orientée objet ou sur l'intérêt du patron MVC dans la programmation pour justifier de cette importance, voici à mon avis le pourquoi de ne pas négliger cette structuration dans une application web.
Dans une application web il est commun de considérer deux types de contrôleurs : le Front Controller, qui gère les requêtes utilisateurs passées au niveau de l'URL et le contrôleur applicatif qui gère de façon générale les interactions entre la vue et le modèle.
Dans les anciennes applications web et encore parmi certaines d'aujourd'hui qui ne sont pas conçues autour d'Ajax, toutes les requêtes utilisateurs passent par l'url et donc par un Front Controller qui centralise tout. Dans un contexte Ajax, ce Front Controller n'est plus seul dans la gestion de ces requêtes utilisateur. Il les partage avec ce que j'appelle tout simplement un Controleur Ajax, qui consistue de fait et de façon générale un Front Controller asynchrone.
En résumé donc, dans une application web Ajax, on peut affirmer que l'on a non plus un Front Controller unique et global mais deux Front Controller : Un Front Controller synchrone et un Front Controller Asynchrone, qui se partagent à eux deux l'ensemble des requêtes utilisateur sur le serveur.
En tant que controleur, le code s'y trouvant, se doit donc d'être structuré de façon logique et claire, je pense que tout le monde en conviendra.
2) Comment créer un contrôleur Ajax spécifique en PHP ?
Tout d'abord, je rappelle de la nécessité de bien séparer le controleur applicatif du Front Controller dans un contexte MVC. Le client / la vue ne doit pas accéder au contrôleur applicatif directement ne serait-ce que par sécurité. On valide la requête et ses paramètres en type et en nature. Et lorsque les données reçues sont conformes, on les transmet au contrôleur applicatif en charge de la requête à traiter. Il est important dans une architecture n-tiers, que chaque tiers applicatif ne fasse pas confiance au premier abord à ce qu'il reçoit de l'autre. C'est d'ailleurs la responsabilité primaire du serveur objet dans une architecture web en bases de données épaisses, que de valider et de mettre en forme les requêtes et données du client auprès du SGBDR qui va les traiter.
Il est important également de ne pas faire du contrôleur Ajax et du contrôleur applicatif correspondant, un seul et unique controleur, même si la tentation peut être grande pour certains. En effet un controleur applicatif spécifique à la responsabilité de gestion du cache des données associées à cette spécificité, responsabilité qu'un Front Controller n'a pas et ne doit pas avoir.
Voici donc la solution que je vous propose et que je vous recommande pour structurer un tel contrôleur au sein de votre application. Même si après lecture la solution paraîtra évidente à certains, elle ne l'est pas toujours.
Beaucoup de choses à dire sur ce code :
- c'est une classe statique qui a l'avantage d'être légère, minimale niveau mémoire (pas d'instanciation, d'abstraction ni autre) et se prête bien au contexte d'exécution Ajax, on imprime le résultat de la requête pour l'envoyer au client ;
- la gestion d'erreur est spécifique: on imprime directement l'erreur et on fait un exit(). => Le retour d'erreur est standardisé pour le navigateur et laissé à JavaScript pour le rendre à l'utilisateur. Cela n'empêche aucunement de loguer au niveau du SGBDR si cela est souhaité ;
- on bloque automatiquement les requêtes non gérées grâce au switch. Et plutôt que de retourner un message "requête non gérée" vous pouvez si vous le souhaitez, générer une erreur 404 ;
- on oblige à standardiser les requêtes Ajax. Il faut ici que le paramètre action soit toujours présent, c'est-à-dire, dans toutes les requêtes pour que la requête soit examinée. On libère ainsi au plus tôt le serveur d'une requête non désirée, et rien n'empêche encore une fois de loguer les tentatives avant de renvoyer une erreur. (Attention au log ici pour ne pas vous faire saturer votre SGBDR ou votre disque dur par des logs intempestifs).
- la classe joue son rôle de Front Controller. Elle filtre les requêtes acceptables avant de les transmettre / faire suivre au contrôleur applicatif dont elle dépend.
Voilà j'espère que ce petit tutoriel vous sera utile et vous aidera à faire progresser vos applications vers un code plus standard, optimisé et plus sûr.
A bientôt.