Cette architecture implémente un système de communication entre microservices avec gestion des transactions distribuées selon le pattern Saga avec compensation.
MonstersApiClient: Responsable uniquement de la communication avec l'API MonstersPlayerApiClient: Responsable uniquement de la communication avec l'API JoueurInvocationService: Orchestre la logique métier d'invocationExternalApiProperties: Centralise la configuration des APIs externes
- Architecture extensible : pour ajouter une nouvelle API externe, créez simplement un nouveau client sans modifier le code existant
- Les clients API peuvent être mockés facilement pour les tests
- Chaque client expose uniquement les méthodes nécessaires à son domaine
- Les services dépendent d'abstractions (injection de dépendances) plutôt que de classes concrètes
- Configuration centralisée :
ExternalApiPropertiesévite la duplication des URLs - Client HTTP réutilisable :
RestClientConfigconfigure un seulRestTemplatepour toutes les APIs - Gestion d'erreurs centralisée :
GlobalExceptionHandlertraite toutes les exceptions
┌─────────────────────────────────────────────────────────────┐
│ InvocationController │
│ (Point d'entrée HTTP) │
└──────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ InvocationService │
│ (Orchestration + Pattern Saga) │
└────┬──────────────────────┬───────────────────────┬─────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌────────────────┐ ┌──────────────────┐
│ Monster │ │ MonstersApi │ │ PlayerApi │
│ Service │ │ Client │ │ Client │
└─────────┘ └────────────────┘ └──────────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ API Monsters │ │ API Joueur │
│ (Externe) │ │ (Externe) │
└──────────────┘ └──────────────┘
- Invocation locale : Génération du monstre
- Création dans API Monsters : Appel POST /api/monsters/create → reçoit
monsterId - Ajout au joueur : Appel POST /api/joueur/add_monster avec
monsterId
Si l'étape 3 échoue :
- Compensation automatique : Suppression du monstre créé à l'étape 2 via DELETE /api/monsters/{monsterId}
- Exception propagée : L'erreur est remontée au contrôleur avec un code HTTP 502
- Erreurs réseau : Timeout, connexion refusée
- Erreurs HTTP : Codes 4xx, 5xx des APIs externes
- Erreurs métier : Le joueur ne peut plus recevoir de monstres
{
"errors": [
{
"code": 502,
"message": "Erreur de communication avec une API externe: ..."
}
]
}external:
api:
monsters-base-url: http://api_monsters:8080
player-base-url: http://api_joueur:8080
connection-timeout: 5000 # en millisecondes
read-timeout: 5000 # en millisecondesLes noms d'hôtes (api_monsters, api_joueur) doivent correspondre aux noms des services dans votre docker-compose.yml.
POST /api/invocation/global-invoque/{playerId}
curl -X POST http://localhost:8080/api/invocation/global-invoque/player123{
"element": "FIRE",
"hp": 100,
"atk": 50,
"def": 30,
"vit": 20,
"skills": [...]
}- Résilience : Compensation automatique en cas d'échec partiel
- Traçabilité : Logs détaillés à chaque étape
- Maintenabilité : Code organisé, responsabilités claires
- Testabilité : Chaque composant peut être testé indépendamment
- Évolutivité : Facile d'ajouter de nouvelles APIs externes
- Circuit Breaker : Utiliser Resilience4j pour éviter les appels répétés à une API défaillante
- Retry Policy : Réessayer automatiquement les appels échoués
- Async Processing : Utiliser des queues (RabbitMQ, Kafka) pour les opérations longues
- Distributed Tracing : Intégrer Sleuth/Zipkin pour tracer les appels inter-services