Bounded Contexts
Introduction
Le découpage des services backend Feelbat est guidé par les principes du Domain-Driven Design (DDD), et plus particulièrement par la notion de Bounded Context.
Un Bounded Context représente une frontière métier clairement définie. Chaque contexte est responsable d'un domaine fonctionnel précis et ne doit pas prendre en charge les responsabilités d'un autre contexte.
Objectif
À la fin de cette page, vous comprendrez :
- Ce qu'est un Bounded Context.
- Pourquoi les services sont découpés par domaine métier.
- Comment déterminer à quel service appartient une fonctionnalité.
- Pourquoi un service ne doit jamais modifier directement le domaine d'un autre service.
Un service représente un domaine métier
Chez Feelbat, un microservice n'est pas créé pour des raisons techniques mais pour porter un domaine métier.
Autrement dit, avant de créer un service, la première question à se poser est :
Quel domaine métier est responsable de cette fonctionnalité ?
Le service est simplement l'implémentation technique de ce domaine.
Un propriétaire unique
Chaque donnée possède un propriétaire unique.
Ce propriétaire est le seul service autorisé à créer, modifier ou supprimer cette donnée.
Les autres services peuvent consulter ces informations, réagir à des événements ou communiquer avec le service propriétaire, mais ils ne doivent jamais modifier directement son domaine.
Warning
Le propriétaire d'une donnée est le seul service autorisé à la modifier.
Exemples
Sensors
Responsable de :
- créer un capteur ;
- modifier un capteur ;
- supprimer un capteur ;
- gérer le cycle de vie d'un capteur ;
- publier les événements liés aux capteurs.
Ne fait pas :
- envoyer des emails ;
- gérer les permissions ;
- gérer des templates PDF.
Remote Action
Responsable de :
- créer une action distante ;
- planifier son exécution ;
- suivre son état ;
- historiser son exécution.
Ne fait pas :
- modifier directement un capteur ;
- gérer la configuration métier.
Lorsqu'une action doit modifier un capteur, elle demande au domaine Sensors d'effectuer cette modification.
Configuration
Responsable de :
- templates PDF ;
- modèles de configuration ;
- normes vibration ;
- configurations dynamiques.
Ne fait pas :
- gérer les capteurs ;
- gérer les utilisateurs ;
- gérer les actions distantes.
Cas pratique
Prenons un exemple concret.
Un utilisateur souhaite modifier la fréquence d'un capteur depuis l'application mobile.
À première vue, on pourrait penser que cette fonctionnalité appartient au service remote-action, puisqu'il s'agit d'une action envoyée à distance.
En réalité, il faut se poser une autre question :
Quel domaine est propriétaire de la fréquence d'un capteur ?
La réponse est : Sensors.
Le rôle de remote-action est uniquement de créer et suivre une demande d'action distante.
Le rôle de sensors est de décider si la modification est valide, de mettre à jour le capteur et de publier les événements associés.
Le scénario devient alors :
Utilisateur
│
▼
Remote Action
│
Création d'une demande
│
▼
Sensors
│
Validation métier
Modification du capteur
Publication de SensorUpdated
Cet exemple illustre une règle importante :
Tip
Un service peut initier une action sur un autre domaine, mais seul le propriétaire de ce domaine est autorisé à modifier ses données.
Comment choisir le bon service ?
Avant d'ajouter une fonctionnalité, posez-vous les questions suivantes :
- Quel domaine métier possède cette donnée ?
- Quel service est déjà responsable de ce domaine ?
- Cette fonctionnalité modifie-t-elle des données appartenant à un autre domaine ?
- Cette responsabilité existe-t-elle déjà dans un autre service ?
Si la réponse à la dernière question est oui, il est souvent préférable d'étendre le service existant plutôt que d'en créer un nouveau.
Les interactions entre domaines
Les domaines ne vivent pas isolés : ils collaborent en permanence.
Cette collaboration doit toujours passer par un contrat explicite, jamais par un accès direct à la base de données d'un autre service.
Les principaux moyens de communication sont :
- une API (GraphQL, HTTP...) ;
- des événements publiés sur Kafka ;
- des messages asynchrones ;
- des ports applicatifs.
Par exemple, lorsqu'une action distante modifie la fréquence d'un capteur, remote-action ne met jamais directement le capteur à jour.
Il demande au domaine sensors d'effectuer la modification. Une fois celle-ci réalisée, sensors publie un événement SensorUpdated auquel les autres services peuvent réagir.
flowchart LR
User[Utilisateur]
RA[remote-action]
Sensors[sensors]
Kafka[Kafka]
ServiceB[service-b]
User --> RA
RA -->|Demande de modification| Sensors
Sensors -->|SensorUpdated| Kafka
Kafka --> ServiceB
Cette approche garantit que chaque domaine reste maître de ses données tout en permettant aux autres services de réagir aux changements sans créer de couplage fort.
Bonnes pratiques
- Un service possède une responsabilité claire.
- Un domaine métier ne doit avoir qu'un seul propriétaire.
- Préférez la collaboration entre services plutôt que le partage de responsabilités.
- Avant de créer un nouveau service, vérifiez qu'il ne s'agit pas simplement d'une extension d'un domaine existant.
Pour aller plus loin
Les concepts présentés ici sont utilisés dans les pages suivantes :
À retenir
- Les microservices Feelbat sont découpés par domaine métier.
- Chaque domaine possède un propriétaire unique.
- Un service ne doit jamais modifier directement les données d'un autre domaine.
- Les interactions entre domaines passent par des contrats explicites.
- Une bonne définition des Bounded Contexts limite le couplage et facilite l'évolution de la plateforme.