Architecture
Vue d'ensemble
Un OAV repose sur une architecture client/serveur. Elle se compose :
- d'une application React pour la partie client ;
- d'une application Express pour la partie serveur ;
- d'une communication GraphQL entre le client et le serveur ;
- d'un service dédié à la persistance des données.
Cette section présente les rÎles de chacun de ces composants ainsi que les flux d'échange.
Composants
Client : application React
L'application React constitue l'interface utilisateur de l'OAV. Elle initie les interactions, déclenche les actions et effectue les appels GraphQL vers le serveur.
Elle est construite avec Vite et s'appuie sur Apollo Client pour le dialogue avec le serveur.
Serveur : application Express
L'application Express traite les requĂȘtes GraphQL, exĂ©cute la logique mĂ©tier et coordonne les appels vers le service de persistance des donnĂ©es.
Elle porte quatre responsabilités :
- exposer le schéma GraphQL consommé par le client ;
- résoudre les transitions entre les vues ;
- lire et écrire les entités ;
- exécuter les tùches asynchrones déclenchées par le parcours.
Service de persistance : OIP Headless
La persistance des données est assurée par le service OIP Headless qui expose une API REST. Le serveur Express interagit avec cette API pour créer, lire, mettre à jour ou supprimer des données.
OIP Headless est une application Elixir bùtie sur Phoenix, Ecto, PostgreSQL et Oban. Elle assure également :
- l'historisation de toutes les écritures et leur annulation par transaction ;
- la programmation des tĂąches et des workflows de tĂąches ;
- l'application des rĂšgles RGPD de chiffrement au repos et de purge automatique ;
- la publication d'évÚnements vers l'OAV via le protocole AMQP.
Services annexes
Service | RĂŽle |
|---|---|
Service de sessions | Ămet et valide les jetons de dĂ©crochage utilisĂ©s Ă l'entrĂ©e du parcours. |
PostgreSQL | Stocke les données d'OIP Headless ainsi que les sessions HTTP de l'OAV. |
RabbitMQ | Achemine les évÚnements entre OIP Headless et l'OAV, et diffuse les notifications aux clients. |
Briques logicielles
L'OAV assemble plusieurs paquets distribués par l'OIP.
Brique | Paquet | RĂŽle |
|---|---|---|
OIP Starter | â | ModĂšle de projet servant de point de dĂ©part Ă un OAV. |
OIP Starter Utils | @fasstech/oip-starter-utils | Socle applicatif : application React, application Express, couche GraphQL, sessions, moteur de transitions et ordonnanceur de tĂąches. |
OIP Core | @fasstech/oip-core | BibliothÚque d'accÚs aux données au-dessus de l'API OIP Headless. |
OIP Tools | @fasstech/oip-tools | Interface en ligne de commande de configuration et de génération de code. |
OIP Features | @fasstech/oip-features-<name> | Fonctionnalités métier réutilisables, installables à la demande. |
Le socle s'appuie par ailleurs sur des utilitaires transverses : @fasstech/rabbitmq-helper pour AMQP, @fasstech/checkenv pour la validation des variables d'environnement, @fasstech/logger pour la journalisation et @fasstech/textit pour l'internationalisation.
Répartition des responsabilités
Savoir oĂč s'exĂ©cute chaque traitement est dĂ©terminant pour concevoir un parcours correctement.
Traitement | Lieu d'exécution |
|---|---|
Rendu de l'interface et interactions | Navigateur. |
Résolution des transitions entre vues | Serveur Express. |
Lecture et écriture des entités | Serveur Express, par appel à OIP Headless. |
Exécution du code d'une tùche | Serveur Express, dans un processus dédié. |
Programmation des tĂąches et des workflows | OIP Headless. |
Historisation, purge et chiffrement | OIP Headless. |
Flux de communication
Transports
Liaison | Protocole |
|---|---|
Navigateur â serveur Express | GraphQL sur HTTP pour les requĂȘtes et les mutations, sur WebSocket pour les souscriptions. |
Serveur Express â OIP Headless | REST sur HTTP, authentifiĂ© par clĂ© d'API. |
OIP Headless â serveur Express | AMQP, file <OAV_ID>.events pour les tĂąches et <OAV_ID>.entities pour les instantanĂ©s de projet. |
Serveur Express â OIP Headless | AMQP, file oip.api.events pour la remontĂ©e des statuts de tĂąches. |
Flux nominal
Le diagramme ci-dessous illustre les interactions entre les différents composants.
sequenceDiagram
actor Alice
Alice->>React App: User interaction
React App->>Express App: GraphQL
Express App->>API: REST
API->>DB: CRUD operationsRésolution d'une transition
Lorsque l'utilisateur passe d'un écran au suivant, la décision est prise cÎté serveur, puis persistée dans le Process.
sequenceDiagram
actor Alice
Alice->>React App: Screen validation
React App->>Express App: GraphQL, action mutation
Express App->>Express App: Evaluation of view transitions
Express App->>API: REST, Process update
Express App-->>React App: Resolved view
React App->>Alice: NavigationExécution d'une tùche asynchrone
Une tĂąche n'est jamais exĂ©cutĂ©e dans le fil de la requĂȘte : elle est programmĂ©e par OIP Headless, qui notifie l'OAV Ă Ă©chĂ©ance.
sequenceDiagram
React App->>Express App: GraphQL, runTask mutation
Express App->>API: REST, task scheduling
API-->>Express App: AMQP, OAV_ID.events queue
Express App->>Express App: Execution in a dedicated process
Express App-->>API: AMQP, oip.api.events queue
Express App-->>React App: GraphQL, subscription notificationĂtat et persistance
L'état courant d'un OAV n'est pas conservé en mémoire par le serveur.
- Le Process, qui porte le projet, la vue active et ses métadonnées, est persisté dans OIP Headless ; il survit à un rechargement de la page comme au redémarrage du serveur ;
- les entités sont persistées dans OIP Headless, chaque écriture étant historisée et réversible ;
- la session HTTP est stockée dans une table PostgreSQL dédiée, et non dans le processus Node ;
- les notifications de tĂąches transitent par RabbitMQ, ce qui permet de servir plusieurs instances de l'OAV.
Déploiement
Un OAV en production mobilise cinq services :
- l'OAV lui-mĂȘme, distribuĂ© sous forme d'image Docker ;
- le service de sessions et sa base de données ;
- OIP Headless ;
- PostgreSQL, hébergeant les données d'OIP Headless et les sessions de l'OAV ;
- RabbitMQ.
Les migrations du modĂšle de donnĂ©es sont appliquĂ©es au dĂ©marrage du conteneur, avant le lancement du serveur. La configuration est entiĂšrement portĂ©e par des variables d'environnement, validĂ©es au dĂ©marrage : un OAV mal configurĂ© s'arrĂȘte immĂ©diatement plutĂŽt que de dĂ©marrer dans un Ă©tat incohĂ©rent.
Résumé
- Le client React porte l'interface, le serveur Express porte la logique et OIP Headless porte les données ;
- les transitions, les accÚs aux entités et l'exécution des tùches ont lieu cÎté serveur ;
- le client dialogue en GraphQL, le serveur en REST avec OIP Headless, et les évÚnements asynchrones circulent en AMQP ;
- l'état de l'OAV est intégralement externalisé, ce qui rend le serveur reproductible et redémarrable.