Cas pratiques Microservices

30 cas pratiques Microservices disponibles. Niveaux : fondamental (10), avancé (10), expert (10).

Fait partie de : Cas pratiques de conception logicielle

FondamentalMicroservices

Ajout d'un timeout sécurisé sur appel inter-service

Contexte Un appel HTTP interne peut rester bloqué indéfiniment. Le Problème Le code suivant ne gère pas de timeout : await fetch("http://service-b:3002/process"); Contraintes Ajouter un AbortController ou mécanisme équivalent pour limiter l’attente à 2 secondes maximum. Livrable attendu Un code modifié intégrant timeout explicite et gestion d’erreur.

microservicestimeoutnodejs+2
FondamentalMicroservices

Configuration d'un Reverse Proxy d'entrée

Contexte Un frontend appelle deux services : - http://localhost:3001/api/users - http://localhost:3002/api/orders Le Problème Le frontend doit maintenant accéder à une seule URL publique : http://localhost/api/* Contraintes Écrire une configuration simple Nginx OU un serveur Node.js (Express + http-proxy) qui redirige : - /api/users vers port 3001 - /api/orders vers port 3002 Livrable attendu Une configuration fonctionnelle centralisant les appels sur un seul port 80.

microservicesreverse proxyapi gateway+2
FondamentalMicroservices

Correction d'un service 'God Object'

Contexte Un fichier unique contient : class OrderService { createOrder() {} calculatePayroll() {} updateInventory() {} } Le Problème Ce service mélange trois domaines métiers distincts. Contraintes Identifier les trois bounded contexts et proposer trois microservices séparés avec leurs endpoints REST principaux. Livrable attendu Une proposition claire de découpage en : OrderService, PayrollService, InventoryService avec routes API associées.

microservicesbounded contextservice design+2
FondamentalMicroservices

Découper un monolithe Express en deux microservices

Contexte Un serveur Express unique gère : - /users - /orders Le Problème Tout est dans le même projet Node.js. Contraintes Proposer une séparation en deux services indépendants avec ports différents et responsabilités distinctes. Livrable attendu Structure de dossiers proposée et définition des endpoints pour chaque service.

microservicesnodejsservice separation+2
FondamentalMicroservices

Implémentation d'un mécanisme de repli (Fallback)

Contexte ServiceA appelle ServiceB via HTTP. Le Problème Si ServiceB est indisponible, ServiceA plante : const response = await fetch("http://service-b:3002/data"); const data = await response.json(); return data; Contraintes Ajouter une gestion d’erreur avec timeout et fallback retournant : { "status": "degraded" } en cas d’échec. Livrable attendu Une version modifiée du code incluant try/catch et logique de repli simple.

microservicesresiliencecircuit breaker+2
FondamentalMicroservices

Implémenter un endpoint health check

Contexte Un orchestrateur doit vérifier l’état d’un microservice. Le Problème Aucun endpoint de supervision n’est disponible. Contraintes Ajouter un endpoint GET /health retournant : { "status": "ok" }. Livrable attendu Un exemple de route Express ou handler HTTP permettant la vérification de santé du service.

microserviceshealth checknodejs+2
FondamentalMicroservices

Implémenter une communication asynchrone simple via file d’attente

Contexte ServiceOrder doit notifier ServiceInventory après création d’une commande. Le Problème Actuellement, ServiceOrder appelle ServiceInventory en HTTP synchrone. Contraintes Proposer une solution asynchrone simple simulée via un publisher et un consumer (exemple avec EventEmitter Node.js). Livrable attendu Un exemple de code montrant publication d’événement OrderCreated et traitement côté Inventory.

microservicesevent drivenasync communication+2
FondamentalMicroservices

Refactoring : Isolation de la persistence entre deux services

Contexte Deux microservices Node.js existent : ServiceUser et ServiceOrder. Chaque service possède sa propre base de données. Le Problème Le code suivant dans ServiceUser effectue un JOIN direct sur la table orders appartenant à ServiceOrder : const result = await db.query("SELECT u.id, o.total FROM users u JOIN orders o ON u.id = o.user_id"); Cela viole le principe Database per Service. Contraintes Supprimer toute dépendance SQL inter-services. ServiceUser doit récupérer les commandes via un appel HTTP vers ServiceOrder. Livrable attendu Réécrire la logique en utilisant un appel API (fetch ou axios) vers ServiceOrder et retourner une réponse agrégée propre.

microservicesdatabase per servicerefactoring+2
FondamentalMicroservices

Refactoring d’un appel direct vers configuration centralisée

Contexte Les URLs des services sont codées en dur : const url = "http://localhost:3002/api/orders"; Le Problème Cela empêche déploiement flexible en environnement cloud. Contraintes Remplacer les valeurs hardcodées par variables d’environnement (process.env) et configuration centralisée. Livrable attendu Un code modifié utilisant process.env.SERVICE_ORDER_URL avec valeur par défaut sécurisée.

microservicesconfigurationenvironment variables+2
FondamentalMicroservices

Suppression de la dépendance binaire entre services

Contexte ServiceUser importe directement un modèle du ServiceOrder : import { OrderModel } from "../service-order/models/OrderModel"; Le Problème Ce couplage casse l’indépendance des déploiements. Contraintes Supprimer l’import direct. Créer un DTO local OrderDTO et simuler un appel API vers ServiceOrder. Livrable attendu Un code modifié utilisant un objet DTO interne et supprimant toute dépendance vers le code source externe.

microservicesdtodecoupling+2
AvancéMicroservices

Agrégation de données via API Gateway

Contexte Un frontend a besoin d’un endpoint unique /dashboard. Le Problème Les données proviennent de ServiceUser et ServiceOrder. Contraintes Implémenter un endpoint /dashboard qui : - Appelle les deux services en parallèle - Agrège les réponses - Retourne un JSON combiné Livrable attendu Un code Express utilisant Promise.all et gestion d’erreurs propre.

microservicesapi gatewayaggregation+2
AvancéMicroservices

Implémenter un Circuit Breaker simplifié

Contexte ServiceA appelle ServiceB régulièrement. Le Problème En cas d’échecs répétés, ServiceA continue d’appeler ServiceB inutilement. Code actuel const res = await fetch("http://service-b:3002/data"); return await res.json(); Contraintes Implémenter un circuit breaker simple : - Après 3 échecs consécutifs, bloquer les appels pendant 10 secondes. - Retourner une réponse fallback pendant la période d’ouverture. Livrable attendu Un code Node.js intégrant compteur d’échecs et logique d’ouverture/fermeture.

microservicescircuit breakerresilience+2
AvancéMicroservices

Implémenter un mécanisme de retry avec backoff exponentiel

Contexte Un microservice dépend d’un service externe instable. Le Problème Un simple échec provoque une erreur immédiate. Contraintes Ajouter un mécanisme de retry : - Maximum 3 tentatives - Backoff exponentiel (ex: 200ms, 400ms, 800ms) - Stopper après succès Livrable attendu Un code JavaScript implémentant la logique de retry proprement encapsulée.

microservicesretryresilience+2
AvancéMicroservices

Implémenter un pattern Saga simplifié

Contexte Création d’une commande implique : 1. Création Order 2. Réservation stock 3. Paiement Le Problème Si paiement échoue, stock reste réservé. Contraintes Implémenter une logique de compensation : - Si étape 3 échoue - Appeler un endpoint pour libérer le stock Livrable attendu Un code orchestrateur gérant étapes successives et compensation en cas d’erreur.

microservicessaga patterndistributed transactions+2
AvancéMicroservices

Implémenter un rate limiter simple sur un endpoint

Contexte Un endpoint public reçoit trop de requêtes. Le Problème Aucune protection contre abus. Contraintes Implémenter un rate limiter simple en mémoire : - Maximum 5 requêtes par IP par minute Livrable attendu Un middleware Express implémentant limitation basique.

microservicesrate limitingexpress+2
AvancéMicroservices

Implémenter un service registry simplifié

Contexte Les services utilisent des URLs codées en dur. Le Problème En cas de changement d’adresse, tout doit être modifié. Contraintes Créer un objet ServiceRegistry central : - register(serviceName, url) - get(serviceName) Livrable attendu Un module JavaScript simulant un registre simple et son utilisation dans les appels inter-services.

microservicesservice registryservice discovery+2
AvancéMicroservices

Isolation de configuration multi-environnements

Contexte Les URLs des services sont codées en dur dans plusieurs fichiers. Le Problème Le déploiement staging/production est risqué. Contraintes Créer un module config.js centralisé utilisant variables d’environnement. - Charger SERVICE_USER_URL - Charger SERVICE_ORDER_URL - Fournir valeurs par défaut Livrable attendu Un module de configuration propre et son utilisation dans les services.

microservicesconfiguration managementenvironment variables+2
AvancéMicroservices

Mettre en place un cache local pour réduire charge inter-service

Contexte ServiceA appelle fréquemment ServiceB pour des données peu changeantes. Le Problème Trop d’appels réseau inutiles. Contraintes Implémenter un cache en mémoire simple avec TTL de 60 secondes. Livrable attendu Un code Node.js intégrant cache Map avec timestamp et invalidation automatique.

microservicescachingperformance optimization+2
AvancéMicroservices

Refactoring : Remplacer un appel synchrone bloquant par une communication asynchrone

Contexte ServiceOrder appelle ServiceInventory en HTTP après chaque création de commande. Le Problème Si ServiceInventory est lent, ServiceOrder devient instable. Code actuel await fetch("http://inventory:3002/reserve", { method: "POST", body: JSON.stringify({ orderId }) }); Contraintes Supprimer l’appel synchrone et implémenter une communication asynchrone simulée via un event bus simple (EventEmitter ou abstraction maison). Livrable attendu Un code montrant la publication d’un événement OrderCreated et un consumer InventoryHandler indépendant.

microservicesevent drivenasync communication+2
AvancéMicroservices

Refactoring : Suppression d’un couplage via modèle partagé

Contexte Deux services partagent une bibliothèque npm interne contenant des entités métier complètes. Le Problème Toute modification casse les deux services. Contraintes Remplacer l’entité partagée par un contrat DTO minimal et validation locale. Livrable attendu Un exemple DTO local et suppression de dépendance à la librairie partagée.

microservicesdtodecoupling+2
ExpertMicroservices

Architecture d'agrégateur tolérant aux défaillances partielles

Contexte Un endpoint /dashboard doit interroger 4 microservices. Le Problème Un seul service en erreur provoque un HTTP 500 global. Contraintes Construire une logique basée sur Promise.allSettled permettant : - Résultats partiels - Indication explicite des services en échec - Temps de réponse maîtrisé Livrable attendu Un agrégateur robuste retournant un JSON cohérent même en cas d'échecs partiels.

architectureapi-gatewayfault-tolerance+2
ExpertMicroservices

Conception d'un orchestrateur Saga avec stockage d'état persistant

Contexte Un système e-commerce doit suivre l'état global d'une transaction distribuée. Le Problème L'état de la transaction est uniquement en mémoire et perdu en cas de crash. Contraintes Concevoir une structure persistante : - idTransaction - status - stepCourante - historique Livrable attendu Une architecture d'orchestrateur capable de reprendre une Saga interrompue après redémarrage.

architecturesaga-patternpersistence+2
ExpertMicroservices

Conception d'un Rate Limiter distribué basé sur Token Bucket

Contexte Une API publique est déployée sur plusieurs instances. Le Problème Un limiteur local ne garantit pas le respect d'un quota global. Contraintes Concevoir : - Un bucket partagé (type Redis abstrait) - Rechargement progressif des tokens - Vérification atomique avant traitement Livrable attendu Une logique distribuée garantissant 100 requêtes max/minute sur l'ensemble du cluster.

architecturerate-limitingdistributed-systems+2
ExpertMicroservices

Correction d'un Bulkhead inexistant provoquant saturation globale

Contexte Une Gateway appelle deux services externes via le même pool de promesses. Le Problème Le service lent monopolise toutes les ressources concurrentes. Code actuel await Promise.all(requests); Contraintes Séparer les pools d'exécution : - 5 requêtes max pour ServiceA - 5 requêtes max pour ServiceB Livrable attendu Une gestion de concurrence isolée empêchant la propagation des lenteurs.

bugfixbulkhead-patternconcurrency-control+2
ExpertMicroservices

Correction d'un worker bloqué par message Poison

Contexte Un worker consomme des messages depuis une file. Le Problème Un message invalide provoque un crash puis redémarrage, créant une boucle infinie. Code actuel process(message); ack(message); Contraintes Ajouter : - Un compteur de tentatives - Un seuil maxRetry - Redirection vers une Dead Letter Queue après dépassement Livrable attendu Un consommateur résilient évitant les boucles infinies et isolant les messages défectueux.

bugfixmessage-queuedlq+2
ExpertMicroservices

Correction d'une Race Condition dans cache distribué

Contexte Plusieurs instances mettent à jour une clé produit:price dans un cache partagé. Le Problème Une écriture ancienne peut écraser une mise à jour plus récente. Code actuel cache.set("product:1", newPrice); Contraintes Ajouter un mécanisme de versioning ou compare-and-set garantissant qu'une écriture n'est appliquée que si la version correspond. Livrable attendu Une logique de mise à jour atomique protégeant contre le write-after-write.

bugfixrace-conditiondistributed-cache+2
ExpertMicroservices

Correction d'une Saga incohérente avec compensation manquante

Contexte Un orchestrateur gère la création d'une commande via trois appels successifs : createOrder, reserveStock et processPayment. Le Problème Le code actuel exécute les étapes séquentiellement sans compensation. Si processPayment échoue, le stock reste réservé et la commande en statut PENDING. Code actuel await createOrder(); await reserveStock(); await processPayment(); Contraintes Ajouter une logique de rollback garantissant : - Si reserveStock échoue → annuler createOrder - Si processPayment échoue → libérer le stock et annuler la commande Livrable attendu Un orchestrateur robuste avec try/catch structuré et compensation explicite pour chaque étape.

bugfixsaga-patterndistributed-transactions+2
ExpertMicroservices

Modélisation d'un Event Store avec mécanisme de Replay

Contexte Un service bancaire doit reconstruire l'état d'un compte à partir d'événements. Le Problème Le modèle actuel stocke uniquement le solde final. Contraintes Concevoir : - Une structure d'événements immuables - Une fonction replay(events) reconstruisant le solde - Gestion des versions d'événements Livrable attendu Un modèle Event Sourcing capable de recalculer l'état métier à partir d'un historique complet.

architectureevent-sourcingddd+2
ExpertMicroservices

Propagation distribuée d'un Correlation-ID

Contexte Une requête traverse plusieurs microservices via HTTP et messages asynchrones. Le Problème Les logs ne permettent pas de corréler les actions liées à une même requête. Contraintes Concevoir : - Middleware injectant correlationId - Propagation automatique via headers - Transmission via payload de messages Livrable attendu Une solution assurant traçabilité complète d'une transaction distribuée.

architecturedistributed-tracingobservability+2
ExpertMicroservices

Réparation d'un Circuit Breaker bloqué sans transition HALF_OPEN

Contexte Un CircuitBreaker possède deux états : CLOSED et OPEN. Le Problème Après passage en OPEN, aucune transition ne permet de tester la disponibilité du service distant. Code actuel if (failures >= 3) { state = "OPEN"; } Contraintes Introduire : - Un état HALF_OPEN - Une fenêtre temporelle avant tentative de reconnexion - Une transition vers CLOSED si succès Livrable attendu Une machine à états complète avec gestion temporelle et transition correcte entre les trois états.

bugfixcircuit-breakerstate-machine+2

Questions originales conçues par CodeDuel. CodeDuel n'est affilié à aucun éditeur ni organisme de certification cité ; les noms de certifications et les marques appartiennent à leurs titulaires et servent uniquement à indiquer le domaine couvert. Signaler un contenu

    Cas pratiques Microservices : 30 mises en situation | CodeDuel