Microservices Designer
Workflow en 8 étapes
1. Cartographier le domaine (Event Storming / DDD)
- Réunir les experts métier et tech ; lister tous les domain events (faits métier passés).
- Regrouper en bounded contexts : chaque contexte a son propre modèle, son langage ubiquitaire.
- Classer : core domain (avantage concurrentiel), supporting, generic (candidat à l'externalisation/SaaS).
Exemple — e-commerce :
Core : Catalogue, Commande, Pricing
Supporting: Notification, Inventaire
Generic : Paiement (Stripe), Auth (Keycloak)
2. Définir les services (règle de taille)
Critères de découpage — un service par bounded context SI :
- ≥ 2 équipes différentes ont besoin de déployer indépendamment
- La scalabilité requise diffère significativement (ex: Catalogue ×10 vs Commande ×2)
- Les exigences de sécurité/compliance diffèrent (PCI-DSS isolé)
Signaux de sur-découpage : appels synchrones en chaîne > 3 sauts, transactions distribuées partout, équipe < 5 devs.
3. Définir les contrats d'API
- REST : OpenAPI 3.1, versionning via URL (
/v1/) ou Accept: application/vnd.api+json;version=2
- gRPC : Protobuf
.proto versionné, backward-compatible (ne jamais supprimer un field)
- Events : AsyncAPI 3.0, schema registry (Confluent, AWS Glue)
# asyncapi snippet — OrderCreated
channels:
order.created:
publish:
message:
payload:
type: object
properties:
orderId: { type: string, format: uuid }
total: { type: number }
required: [orderId, total]
4. Choisir le pattern de communication
| Besoin |
Pattern |
Outil |
| Requête/réponse immédiate |
REST / gRPC |
Axios, Feign, grpc-go |
| Faible couplage, tolérance à la latence |
Message async |
Kafka, RabbitMQ, Azure SB |
| Workflow long multi-services |
Saga orchestrée |
Temporal, MassTransit Saga |
| Cohérence éventuelle acceptable |
Saga chorégraphiée |
Events Kafka + handlers |
| Agrégation de données cross-services |
GraphQL federation |
Apollo Federation v2 |
Règle : préférer l'asynchrone par défaut ; n'utiliser le synchrone que pour les cas UX qui exigent une réponse immédiate.
5. Données — database per service
❌ Service A ──┐
├── shared DB (couplage fort, migration impossible indépendamment)
❌ Service B ──┘
✅ Service A ── DB A (Postgres)
✅ Service B ── DB B (MongoDB)
✅ Service C ── DB C (Redis)
Patterns avancés :
- CQRS : séparer Command model (write) et Query model (read-optimized, répliqué via events)
- Event Sourcing : stocker les events bruts (EventStoreDB, Kafka compacted topic) ; reconstruire l'état à la demande
- Saga : chaque step publie un event de succès ou compensation en cas d'échec
6. Résilience — checklist obligatoire
// .NET — Polly v8 (2026)
services.AddHttpClient<IOrderClient, OrderClient>()
.AddResilienceHandler("order-pipeline", builder =>
{
builder.AddRetry(new HttpRetryStrategyOptions
{
MaxRetryAttempts = 3,
BackoffType = DelayBackoffType.Exponential
});
builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions
{
SamplingDuration = TimeSpan.FromSeconds(30),
FailureRatio = 0.5
});
builder.AddTimeout(TimeSpan.FromSeconds(5));
});
- Bulkhead : thread pool séparé par dépendance critique
- Fallback : retourner une réponse dégradée plutôt qu'une erreur 500
- Idempotency key : toujours sur les endpoints mutatifs (
Idempotency-Key: <uuid>)
7. Observabilité — stack minimale 2026
Traces → OpenTelemetry SDK → Jaeger / Tempo
Métriques → Prometheus → Grafana
Logs → structured JSON → Loki / ELK
Alertes → Alertmanager / PagerDuty
# Python — OTel auto-instrumentation FastAPI
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
FastAPIInstrumentor.instrument_app(app, tracer_provider=tracer_provider)
Règles :
- Correlation ID propagé dans tous les headers (
traceparent W3C standard)
- Health checks :
/healthz/live (process up) + /healthz/ready (dépendances OK)
- SLO défini par service : ex. p99 < 200 ms, error rate < 0.1 %
8. Migration d'un monolithe — Strangler Fig
Phase 1 : Façade devant le monolithe (reverse proxy / API Gateway)
Phase 2 : Extraire Service X derrière la façade, redirections progressives
Phase 3 : Supprimer le code correspondant du monolithe
Phase 4 : Répéter par service, jamais de big bang
Outils : Kong / YARP en façade, feature flags pour basculer le trafic, canary deployment (1 % → 10 % → 100 %).
Anti-patterns & pièges
| Anti-pattern |
Symptôme |
Correction |
| Distributed monolith |
Déploiement coordonné obligatoire |
Revoir les bounded contexts |
| Nano-services |
> 20 services, équipe < 5 devs |
Fusionner les services trop fins |
| Shared DB |
Migration impossible, couplage fort |
Database per service + events |
| Appels synchrones en cascade |
Latence additive, failure amplification |
Async + cache local |
| Pas d'idempotence |
Doublons en cas de retry |
Idempotency key systématique |
| Contrats implicites |
Breaking changes non détectés |
Contract testing (Pact) en CI |
Critères de décision — monolithe vs microservices
Microservices recommandés si ≥ 3 critères :
☐ Équipes > 2 squads avec ownership distinct
☐ Exigences de scalabilité très différentes par domaine
☐ Besoin de déploiements indépendants fréquents (> 2×/semaine par domaine)
☐ Technologies différentes justifiées par domaine
☐ Compliance / isolation sécurité obligatoire par périmètre
Sinon : Modulith d'abord (modules bien isolés dans un monolithe),
migration service par service quand un critère se déclenche.
Bonnes pratiques 2026
- Service mesh (Istio, Linkerd, Dapr) : mTLS automatique, observabilité L7, traffic management sans code applicatif.
- GitOps : un repo par service, ArgoCD/Flux pour les déploiements Kubernetes.
- Contract testing avec Pact en CI : valider que producer et consumer restent compatibles avant merge.
- Platform engineering : fournir un Internal Developer Portal (Backstage) avec templates de service pré-configurés (OTel, health, Dockerfile, CI).
- Chaque ADR dans
docs/adr/NNNN-titre.md (format Nygard) ; lier depuis le README du service.
Communication Rules — MANDATORY
- Ultra-concise. No filler, no preamble, no pleasantries.
- Never say "happy to help", "sure!", "great question", "let me", or similar.
- Tool first, talk second. Act before explaining.
- Result first. Lead with outcome, not process.
- Stop when done. No summary, no recap, no trailing commentary.
- No politeness wrappers. Direct and blunt.
- Minimum words. If one word works, do not use ten.
- No unsolicited explanations.
- No emoji unless asked.
1---2name: dev-microservices-designer3description: Conception et découpage d'architecture microservices — DDD, bounded contexts, patterns de communication, migration de monolithe. À utiliser pour concevoir ou migrer vers des microservices. Se déclenche avec "microservices", "découpage", "bounded context", "service mesh", "décomposition monolithe", "architecture distribuée". Also triggers on "split into microservices", "service boundaries".4---56# Microservices Designer78## Workflow en 8 étapes910### 1. Cartographier le domaine (Event Storming / DDD)11- Réunir les experts métier et tech ; lister tous les **domain events** (faits métier passés).12- Regrouper en **bounded contexts** : chaque contexte a son propre modèle, son langage ubiquitaire.13- Classer : core domain (avantage concurrentiel), supporting, generic (candidat à l'externalisation/SaaS).1415```16Exemple — e-commerce :17 Core : Catalogue, Commande, Pricing18 Supporting: Notification, Inventaire19 Generic : Paiement (Stripe), Auth (Keycloak)20```2122### 2. Définir les services (règle de taille)23Critères de découpage — un service par bounded context SI :24- ≥ 2 équipes différentes ont besoin de déployer indépendamment25- La scalabilité requise diffère significativement (ex: Catalogue ×10 vs Commande ×2)26- Les exigences de sécurité/compliance diffèrent (PCI-DSS isolé)2728Signaux de sur-découpage : appels synchrones en chaîne > 3 sauts, transactions distribuées partout, équipe < 5 devs.2930### 3. Définir les contrats d'API31- **REST** : OpenAPI 3.1, versionning via URL (`/v1/`) ou `Accept: application/vnd.api+json;version=2`32- **gRPC** : Protobuf `.proto` versionné, backward-compatible (ne jamais supprimer un field)33- **Events** : AsyncAPI 3.0, schema registry (Confluent, AWS Glue)3435```yaml36# asyncapi snippet — OrderCreated37channels:38 order.created:39 publish:40 message:41 payload:42 type: object43 properties:44 orderId: { type: string, format: uuid }45 total: { type: number }46 required: [orderId, total]47```4849### 4. Choisir le pattern de communication5051| Besoin | Pattern | Outil |52|---|---|---|53| Requête/réponse immédiate | REST / gRPC | Axios, Feign, grpc-go |54| Faible couplage, tolérance à la latence | Message async | Kafka, RabbitMQ, Azure SB |55| Workflow long multi-services | Saga orchestrée | Temporal, MassTransit Saga |56| Cohérence éventuelle acceptable | Saga chorégraphiée | Events Kafka + handlers |57| Agrégation de données cross-services | GraphQL federation | Apollo Federation v2 |5859**Règle** : préférer l'asynchrone par défaut ; n'utiliser le synchrone que pour les cas UX qui exigent une réponse immédiate.6061### 5. Données — database per service6263```64❌ Service A ──┐65 ├── shared DB (couplage fort, migration impossible indépendamment)66❌ Service B ──┘6768✅ Service A ── DB A (Postgres)69✅ Service B ── DB B (MongoDB)70✅ Service C ── DB C (Redis)71```7273Patterns avancés :74- **CQRS** : séparer Command model (write) et Query model (read-optimized, répliqué via events)75- **Event Sourcing** : stocker les events bruts (EventStoreDB, Kafka compacted topic) ; reconstruire l'état à la demande76- **Saga** : chaque step publie un event de succès ou compensation en cas d'échec7778### 6. Résilience — checklist obligatoire7980```csharp81// .NET — Polly v8 (2026)82services.AddHttpClient<IOrderClient, OrderClient>()83 .AddResilienceHandler("order-pipeline", builder =>84 {85 builder.AddRetry(new HttpRetryStrategyOptions86 {87 MaxRetryAttempts = 3,88 BackoffType = DelayBackoffType.Exponential89 });90 builder.AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions91 {92 SamplingDuration = TimeSpan.FromSeconds(30),93 FailureRatio = 0.594 });95 builder.AddTimeout(TimeSpan.FromSeconds(5));96 });97```9899- **Bulkhead** : thread pool séparé par dépendance critique100- **Fallback** : retourner une réponse dégradée plutôt qu'une erreur 500101- **Idempotency key** : toujours sur les endpoints mutatifs (`Idempotency-Key: <uuid>`)102103### 7. Observabilité — stack minimale 2026104105```106Traces → OpenTelemetry SDK → Jaeger / Tempo107Métriques → Prometheus → Grafana108Logs → structured JSON → Loki / ELK109Alertes → Alertmanager / PagerDuty110```111112```python113# Python — OTel auto-instrumentation FastAPI114from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor115FastAPIInstrumentor.instrument_app(app, tracer_provider=tracer_provider)116```117118Règles :119- **Correlation ID** propagé dans tous les headers (`traceparent` W3C standard)120- Health checks : `/healthz/live` (process up) + `/healthz/ready` (dépendances OK)121- SLO défini par service : ex. p99 < 200 ms, error rate < 0.1 %122123### 8. Migration d'un monolithe — Strangler Fig124125```126Phase 1 : Façade devant le monolithe (reverse proxy / API Gateway)127Phase 2 : Extraire Service X derrière la façade, redirections progressives128Phase 3 : Supprimer le code correspondant du monolithe129Phase 4 : Répéter par service, jamais de big bang130```131132Outils : Kong / YARP en façade, feature flags pour basculer le trafic, canary deployment (1 % → 10 % → 100 %).133134---135136## Anti-patterns & pièges137138| Anti-pattern | Symptôme | Correction |139|---|---|---|140| Distributed monolith | Déploiement coordonné obligatoire | Revoir les bounded contexts |141| Nano-services | > 20 services, équipe < 5 devs | Fusionner les services trop fins |142| Shared DB | Migration impossible, couplage fort | Database per service + events |143| Appels synchrones en cascade | Latence additive, failure amplification | Async + cache local |144| Pas d'idempotence | Doublons en cas de retry | Idempotency key systématique |145| Contrats implicites | Breaking changes non détectés | Contract testing (Pact) en CI |146147---148149## Critères de décision — monolithe vs microservices150151```152Microservices recommandés si ≥ 3 critères :153 ☐ Équipes > 2 squads avec ownership distinct154 ☐ Exigences de scalabilité très différentes par domaine155 ☐ Besoin de déploiements indépendants fréquents (> 2×/semaine par domaine)156 ☐ Technologies différentes justifiées par domaine157 ☐ Compliance / isolation sécurité obligatoire par périmètre158159Sinon : Modulith d'abord (modules bien isolés dans un monolithe),160 migration service par service quand un critère se déclenche.161```162163---164165## Bonnes pratiques 2026166167- **Service mesh** (Istio, Linkerd, Dapr) : mTLS automatique, observabilité L7, traffic management sans code applicatif.168- **GitOps** : un repo par service, ArgoCD/Flux pour les déploiements Kubernetes.169- **Contract testing** avec Pact en CI : valider que producer et consumer restent compatibles avant merge.170- **Platform engineering** : fournir un Internal Developer Portal (Backstage) avec templates de service pré-configurés (OTel, health, Dockerfile, CI).171- Chaque ADR dans `docs/adr/NNNN-titre.md` (format Nygard) ; lier depuis le README du service.172173174## Communication Rules — MANDATORY175176- Ultra-concise. No filler, no preamble, no pleasantries.177- Never say "happy to help", "sure!", "great question", "let me", or similar.178- Tool first, talk second. Act before explaining.179- Result first. Lead with outcome, not process.180- Stop when done. No summary, no recap, no trailing commentary.181- No politeness wrappers. Direct and blunt.182- Minimum words. If one word works, do not use ten.183- No unsolicited explanations.184- No emoji unless asked.