Conférence Devoxx FR 2022
"Microservices, DDD et bootstrapping pour faire un départ lancé"
Résumé de la présentation :
Associer microservices et conception DDD (Domain-Driven Design) semble une évidence. Le découpage en contextes et les différentes couches d’architecture constituent un cadre séduisant pour bâtir des microservices avec une structure stéréotypée. Mais si on souhaite respecter les fondamentaux du DDD et garantir l’isolation des différentes couches on arrive rapidement à une structure de projet basée sur plusieurs modules qui peuvent devenir complexes à gérer et qui risquent de ralentir le cycle de développement, en particulier lors de la phase de démarrage.
Cette présentation est un retour d’expérience d’un grand projet dans lequel le générateur de code Telosys a été utilisé pour automatiser la phase d’amorçage de chaque microservice.
Environnement technique : Java, SpringBoot, Telosys
4. • Client: secteur public
• Organisation: itératif, ~130 développeurs
• Legacy:
• Important de ~17 années, ~100
modules
• Architecture: 3-tier monolithique Java
• Modernisation:
• Débutée en 2021, ~20 microservices
• Architecture: 3-tier microservice
Legacy
Cloud Cloud – IA
Contexte du projet
5. Contexte du projet
Cloud
Cloud – IA
Legacy
Infrastructure: Cloud
Système d’exploitation
Orchestration de conteneurs: Kubernetes
Moteur de conteneurs: Containerd
Service Mesh: Istio
Microservice:
Spring-boot
Microservice:
Spring-boot
Microservice:
Spring-boot
Base de données:
PostgreSQL
Appli mobile:
Xamarin
SPA:
Vue.js
Batch:
Spring batch
Batch:
Spring batch
9. Projet microservice Framework « léger »
( fonctionnalités techniques, librairies communes,
configuration des plugins de compilation/packaging)
Structuration Maven
10. Modules Maven
Parent
Domain
Infra SQL
Infra AMQP
Application
DTO
Microservice
etc...
Tout ça pour
chaque microservice ?
Comment bien démarrer ?
=> Copier/Coller ?
=> Bootstraping ?
REST API
11. Génération de code… ?
Black
box
Model
Résultat imposé !
Fichiers
générés
Objections classiques :
• C’est lourd
• Le code généré n’est pas propre ou non conforme aux attentes
• Souvent intrusif : le générateur impose des choix (style de code, framework, etc )
18. Modèle Telosys
1
Une entité est décrite à l’aide d’un
DSL (Domain-Specific Language)
Grammaire très simple et
extensible avec des « tags »
DSL
#tag
1 modèle = 1 répertoire
Modèle « léger » basé sur des fichiers « texte » (pas d’UML)
1 entité = 1 fichier texte ( « .entity » )
19. @AggregateRoot
@DbTable(T_ORDER)
#MyEntityTag
Order {
// Id ( Primary Key )
num : int { @Id @NotNull @Label("order number") } ;
orderDate : date { @NotNull @Label("order date")} ;
status : short { @NotNull @DefaultValue(0) #MyTag(xy) };
comment : string { @Size(120) } ;
// FK referencing Customer
customerId : int { @FK(Customer) } ;
// Links
items : OrderItem[] ; // Many
deliveryAddress : DeliveryAddress ; // One
// No link to Customer (not in the aggregate, just FK)
}
Attributs
- Primary Key
- Basic attrib.
- Foreign Key
Liens
- to one
- to many
@xxx Annotations
Composite PK & FK
Fichier « .entity »
Types neutres
Entité
#xxx Tags
20. Visualisation du modèle avec PlantUML
Bundle
(templates)
Model
(entities)
Templates
pour PlantUML
Entités du
microservice
Fichier « .plantuml »
21. Génération du module « domain »
Bundle
(templates)
Model
(entities)
Templates
dédiés au
« domain »
Entités du
microservice
30. REST API « Contract First »
« Code First »
« Contract First »
Contract
( Open API)
Il va falloir gérer 2 modèles ( Telosys + Open API ) ?
Contract
( Open API)
Code
Code
31. Génération des fichiers OpenAPI
Bundle
(templates)
Model
Telosys
(entities)
Templates pour
générer une
spec Open API
Meta-model
“Telosys”
Meta-model
“Open API”
M2M
DTO &
interfaces
Contract
( Open API)
Code
« Model to Model »
.yaml
33. Ce qu’on ne vous a pas montré…
• Adaptation spécifique au framework du projet
• Génération des tests unitaires (JUnit, …)
• Génération des tests d’intégration (Postman, SOAPUI, …)
• Bootstrapping des batchs (Spring Batch)
• Bootstrapping des IHM (CRUD)
34. Les gains
• Productivité
démarrage rapide,
réduction de la charge de travail & réduction des délais
• Simplification
certaines parties du code peuvent être générées intégralement
et deviennent « invisibles » pour le développeur (DTO, mappers, …)
• Standardisation
respect des règles de développement dans les templates
• Qualité
application des bonnes pratiques dans les templates
(Clean Code, Software Craftsmanship, tests unitaires, …)
35. Jusqu’ou aller ?
• Trouver un équilibre
• Privilégier les « quick wins »
• Savoir s’arrêter
Temps investi
dans les templates
Temps de développement gagné (+qualité)
37. Flexibilité & adaptabilité
• Capacité à générer tout type de code
(langages, frameworks, autres modèles) => un seul outil pour tout générer
• Le projet décide de ses choix et le générateur s’adapte
- adaptation au socle du projet (ex : MyBatis, Spring Boot + JAX-RS)
- adaptation au framework du projet (héritage, pom parents, etc)
- respect des conventions et standards de développement du projet
• Le modèle doit être extensible (ex : les #tags)
• Les templates doivent être facilement adaptables
• Possibilité de gérer les clés primaires composites
41. @telosys tag "telosys" groups/1340197/ channel "Telosys"
https://www.telosys.org/
• Telosys CLI :
https://github.com/telosys-tools-bricks/telosys-cli
• Telosys Eclipse plugin :
https://github.com/telosys-eclipse-v3/TelosysToolsPlugin
All stars are welcome ;-)
Stay tuned !
42. Spring-Data-JDBC vs. MyBatis vs. Implémentation JPA
Spring-Data-JDBC MyBatis Impl. JPA
Framework de persistance de type ORM X X
Indépendance du code avec le SGBD X X
Gestion des relations dans le modèle objet (aggregat) X X
Ecriture des requêtes avec le language natif du SGBD X X X
Gestion des clés composées X X
Chargement différé des relations (ex: lazy loading) X X
Cache de niveau 2 X X
Gestion des procédures stockées X X X
Gestion des géométries X X X