Frontend comme serveur REST côté client : Discipline architecturale au lieu du chaos de la gestion d'état
Le développement frontend moderne a depuis longtemps dépassé le stade des manipulations DOM et des mises en page simples. D'un point de vue architectural, les applications SPA et SSR accomplissent la même tâche que les systèmes serveurs classiques : elles reçoivent des signaux entrants, traitent les données selon les règles de la logique métier, et renvoient une vue prête à l'emploi. La différence ne réside que dans l'environnement d'exécution et le protocole d'interaction. Plutôt que d'inventer sans fin de nouvelles abstractions à chaque sortie de framework, il est plus efficace d'appliquer directement les patterns serveur éprouvés au code client.
Évolution du rôle : De l'hypermedia au rendu côté client
À l'origine, le web fonctionnait sur un schéma transparent : le navigateur demandait une URL, le serveur générait du HTML, et le client affichait le résultat. Étonnamment, le HTML standard est une implémentation native du principe HATEOAS. Le serveur renvoie non seulement des données, mais l'état de l'interface accompagné des transitions disponibles : liens, formulaires avec méthodes spécifiées, boutons d'action. Le client ne stocke pas à l'avance une carte des routes — il réagit à ce qui est autorisé dans le contexte actuel.
L'approche moderne avec les API JSON n'a fait que changer le format de transmission de l'état, mais pas son essence. Le même principe peut s'exprimer via le format HAL :
{
"id": 42,
"status": "pending",
"_links": {
"self": { "href": "/orders/42" },
"cancel": { "href": "/orders/42/cancel", "method": "POST" },
"detail": { "href": "/orders/42/detail" }
}
}
La formule UI = f(state) existait bien avant l'avènement du DOM virtuel. Auparavant, l'état était transmis intégralement depuis le serveur distant ; maintenant, il est calculé localement et mis à jour de manière incrémentale. Le problème n'est pas né du changement de paradigme, mais de la perte de discipline architecturale lors du portage de la logique vers le client.
Les événements comme requêtes : Cartographie des couches architecturales
Dans le développement backend, les interactions sont strictement réglementées. Le contrôleur accepte une requête HTTP, valide les données d'entrée, les transforme en DTO, et délègue le traitement à la couche service. Le service travaille avec le modèle de domaine, tandis que le référentiel gère la persistance. Les frontières de responsabilité sont claires et indépendantes du langage ou du framework spécifique.
En frontend, les actions utilisateur (clics, saisie, défilement, messages WebSocket) servent d'analogue complet aux requêtes HTTP. Événement = Requête. Cependant, au lieu de contrôleurs unifiés, l'écosystème a engendré un zoo de termes : stores, composables, hooks, atoms, runes, view models. Chaque outil impose sa propre philosophie de gestion d'état, brouillant les frontières architecturales. Il est plus logique d'aligner l'architecture client sur les standards serveur :
Frontend
웃 → Event → Controller → Service → Repository → → → → → → Rest API
│ │ │ ↑ │ │
│ │ │ │ └─ Builds HTTP Request │
│ │ │ │ │
│ │ │ └─ Business logic │
│ │ │ │
│ │ └─ Extracts, validates & maps to DTO │
│ │ │
│ └─ Environment detail - Browser Event │
│ │
│ │
│ │
└─ ← Response ← Controller ← Service ← Repository ← ← ← ← ← ← Rest API
│ │ │
│ │ └─ Maps to Domain Model
│ │
│ └─ Maps to framework format: JSX/Vue template
│
└─ Automatically mapped to HTML chunk from JSX by framework
Contrôleurs à état et détails d'infrastructure
La principale objection au portage direct des patterns serveur concerne l'état. Les contrôleurs REST classiques sont conçus comme sans état pour l'évolutivité horizontale. Le frontend, par définition, opère dans un contexte à état : session utilisateur, cache local, états de formulaires et d'éléments UI vivent en mémoire du navigateur. Ce n'est pas une contradiction, mais une caractéristique de l'environnement. En backend, des patterns à état similaires sont utilisés dans le développement de jeux, les passerelles IoT, et les services de streaming basés sur gRPC ou WebSockets.
Les hooks, signaux et atoms réactifs doivent être vus uniquement comme des détails d'infrastructure. Ce sont des mécanismes que le framework utilise pour des mises à jour DOM efficaces et le suivi des dépendances. L'erreur est que les développeurs commencent à stocker les règles métier et la logique de validation directement dans ces primitives. Les gestionnaires d'état masquent souvent des abstractions qui fuient, permettant aux composants UI de dépendre directement de la structure du store. Introduire une couche contrôleur et service résout cela en isolant la logique métier du système réactif du framework.
Application pratique de la discipline serveur
Adopter les approches backend ne nécessite pas d'abandonner React, Vue ou Solid. Il s'agit de structurer le code au sein de l'écosystème. Pour atteindre la prévisibilité et réduire la charge cognitive lors de l'onboarding de nouveaux développeurs, suivez simplement quelques principes :
- Validation stricte des événements entrants et des données API à la frontière de l'application (en utilisant Zod, Yup ou des guards TypeScript).
- Transformation des réponses brutes du serveur et des entrées utilisateur en DTOs avant de les passer à la couche métier.
- Isolation de la logique de domaine dans des services purs qui n'importent pas de hooks du framework et ne connaissent rien au DOM.
- Utilisation de référentiels pour abstraire les sources de données (LocalStorage, IndexedDB, REST, GraphQL).
- Les contrôleurs agissent comme le point de connexion unique : ils mappent les événements vers les appels de service, et les résultats vers les props pour les composants présentiels.
Cette approche rend le code indépendant du framework. La logique métier est facilement couverte par des tests unitaires sans mocks de renderer, et la migration d'une solution UI à une autre n'affecte qu'une fine couche d'adaptateur.
Points clés à retenir
- Une app frontend est architecturalement équivalente à un serveur REST déployé dans le navigateur : les événements remplacent les requêtes HTTP, et le rendu forme la réponse.
- Le HTML a historiquement implémenté les principes HATEOAS, livrant l'état et les actions disponibles au client simultanément.
- La variété de termes (stores, composables, atoms) crée une illusion de nouveauté mais brouille souvent les frontières de responsabilité et complique la maintenance.
- Les hooks et signaux sont des primitives d'infrastructure du framework, pas des endroits pour les règles métier ou la validation complexe.
- Appliquer la discipline serveur (DTOs, contrôleurs, services, référentiels) réduit le couplage du code, simplifie les tests, et rend l'architecture indépendante des frameworks UI spécifiques.
— Editorial Team
Aucun commentaire pour le moment.