Advanced (Mis à jour: 03/06/2026)

Microservices avec Claude Code : limites, API, Compose et tests

Microservices avec Claude Code : frontières, contrats API, Compose, tests, observabilité et rollout.

Microservices avec Claude Code : limites, API, Compose et tests

Les microservices consistent à découper une grande application en petits services indépendants qui collaborent via des API ou des événements. Claude Code devient utile quand il ne se limite pas à générer des dossiers, mais vérifie aussi les frontières de services, les contrats API, la propriété des données, Docker Compose, la passerelle, l’observabilité, les tests et le plan de déploiement.

Il faut rester pragmatique : les microservices n’améliorent pas automatiquement un produit. Ils ajoutent des appels réseau, de la compatibilité d’API, des transactions distribuées, de la corrélation de logs et des rollbacks plus complexes. Si le domaine change encore tous les jours, commencez par un monolithe modulaire. Pour les bases, voir développement API avec Claude Code, Docker Compose, logging et monitoring et architecture événementielle.

Gardez des références officielles comme points d’ancrage : Anthropic Claude Code overview, Docker Compose documentation et OpenAPI Specification 3.1. Elles aident à distinguer les suggestions de Claude Code du contrat réellement exploité.

Commencer Par Les Frontières

Le prompt initial doit demander une justification, pas seulement une liste de services.

Tu es architecte reviewer pour découper une application e-commerce en microservices.

Contexte:
- Le flux de commande change souvent.
- Le stock doit évoluer séparément à cause de l'intégration entrepôt.
- Paiement et notifications ne doivent pas bloquer le catalogue.

À produire:
1. Services candidats et responsabilités.
2. Données possédées par chaque service.
3. Interactions synchrones par API.
4. Interactions asynchrones par événement.
5. Ce qui doit rester dans le monolithe pour l'instant.

Contraintes:
- Pas de tables partagées.
- Pas de noms de tables internes dans les API.
- Pas de logique métier dans la gateway.
- Démarrage local avec Docker Compose.

Les documents Microsoft Microservices architecture guide, AKS microservices reference architecture et API Management gateway overview donnent un cadre officiel pour l’autonomie, le routage et l’exploitation.

Contrat API Et Données

Écrivez le contrat avant le code.

openapi: 3.1.0
info:
  title: Order Service API
  version: 1.0.0
paths:
  /orders:
    post:
      summary: Create an order after reserving inventory
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [customerId, items]
              properties:
                customerId:
                  type: string
                items:
                  type: array
                  minItems: 1
                  items:
                    type: object
                    required: [sku, quantity]
                    properties:
                      sku:
                        type: string
                      quantity:
                        type: integer
                        minimum: 1
      responses:
        "201":
          description: Order accepted
        "409":
          description: Inventory could not be reserved
ServicePossèdePeut appelerNe doit pas faire
gatewayaucune donnée métierorder, inventorycalculer stock ou remises
order-serviceorders, order_itemsinventory API, order-eventslire les tables inventory
inventory-servicestock, reservationsrien au départlire les tables orders
notification-servicedelivery logsorder-eventschanger l’état d’une commande

Pour afficher commande et stock sur le même écran, évitez le JOIN entre bases de services. Préférez composition d’API, modèle de lecture, index de recherche ou cache alimenté par événements.

Pour les reviews, gardez un petit service-inventory.json dans le dépôt. Les humains décident les frontières; Claude Code vérifie si un changement les viole.

{
  "services": [
    {
      "name": "gateway",
      "owns": [],
      "mayCall": ["order-service", "inventory-service"],
      "mustNot": ["store business data", "calculate discounts"]
    },
    {
      "name": "order-service",
      "owns": ["orders", "order_items"],
      "mayCall": ["inventory-service"],
      "mustNot": ["read inventory tables directly"]
    },
    {
      "name": "inventory-service",
      "owns": ["stock", "reservations"],
      "mayCall": [],
      "mustNot": ["change order status"]
    }
  ],
  "releaseRules": [
    "no shared database tables",
    "public APIs hide internal table names",
    "every service has healthcheck, logs, tests, and rollback notes"
  ]
}

Exemple Exécutable

mkdir microservices-demo
cd microservices-demo
mkdir services
npm init -y
npm pkg set type=module
npm install express zod pino redis undici

compose.yaml:

services:
  gateway:
    image: node:22-alpine
    working_dir: /workspace
    command: node services/service.mjs
    environment:
      SERVICE: gateway
      PORT: 3000
      ORDER_URL: http://order-service:3000
      INVENTORY_URL: http://inventory-service:3000
    ports:
      - "8080:3000"
    volumes:
      - .:/workspace
    depends_on:
      - order-service
      - inventory-service
  order-service:
    image: node:22-alpine
    working_dir: /workspace
    command: node services/service.mjs
    environment:
      SERVICE: order
      PORT: 3000
      INVENTORY_URL: http://inventory-service:3000
      REDIS_URL: redis://redis:6379
    volumes:
      - .:/workspace
    depends_on:
      redis:
        condition: service_healthy
      inventory-service:
        condition: service_started
  inventory-service:
    image: node:22-alpine
    working_dir: /workspace
    command: node services/service.mjs
    environment:
      SERVICE: inventory
      PORT: 3000
    volumes:
      - .:/workspace
  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 10

services/service.mjs:

import express from "express";
import pino from "pino";
import { createClient } from "redis";
import { request } from "undici";
import { z } from "zod";
import { randomUUID } from "node:crypto";

const service = process.env.SERVICE ?? "inventory";
const port = Number(process.env.PORT ?? 3000);
const log = pino({ name: service });

function base(name) {
  const app = express();
  app.use(express.json());
  app.use((req, res, next) => {
    req.requestId = req.header("x-request-id") ?? randomUUID();
    res.setHeader("x-request-id", req.requestId);
    next();
  });
  app.get("/health", (_req, res) => res.json({ ok: true, service: name }));
  return app;
}

function inventory() {
  const app = base("inventory");
  const stock = new Map([["sku-1", 5], ["sku-2", 2]]);
  const Reserve = z.object({ sku: z.string().min(1), quantity: z.number().int().positive() });
  app.get("/inventory/:sku", (req, res) => res.json({ sku: req.params.sku, quantity: stock.get(req.params.sku) ?? 0 }));
  app.post("/inventory/reservations", (req, res) => {
    const parsed = Reserve.safeParse(req.body);
    if (!parsed.success) return res.status(400).json({ error: parsed.error.flatten() });
    const available = stock.get(parsed.data.sku) ?? 0;
    if (available < parsed.data.quantity) return res.status(409).json({ error: "insufficient_stock", available });
    stock.set(parsed.data.sku, available - parsed.data.quantity);
    log.info({ requestId: req.requestId, sku: parsed.data.sku }, "reserved");
    res.status(201).json({ sku: parsed.data.sku, remaining: stock.get(parsed.data.sku) });
  });
  app.listen(port, () => log.info({ port }, "inventory started"));
}

async function order() {
  const app = base("order");
  const redis = createClient({ url: process.env.REDIS_URL ?? "redis://localhost:6379" });
  await redis.connect();
  const Order = z.object({
    customerId: z.string().min(1),
    items: z.array(z.object({ sku: z.string().min(1), quantity: z.number().int().positive() })).min(1),
  });
  app.post("/orders", async (req, res) => {
    const parsed = Order.safeParse(req.body);
    if (!parsed.success) return res.status(400).json({ error: parsed.error.flatten() });
    for (const item of parsed.data.items) {
      const response = await request(`${process.env.INVENTORY_URL}/inventory/reservations`, {
        method: "POST",
        headers: { "content-type": "application/json", "x-request-id": req.requestId },
        body: JSON.stringify(item),
      });
      if (response.statusCode >= 400) return res.status(response.statusCode).json(await response.body.json());
    }
    const order = { id: randomUUID(), ...parsed.data, status: "accepted" };
    await redis.xAdd("order-events", "*", { type: "OrderAccepted", payload: JSON.stringify(order) });
    res.status(201).json(order);
  });
  app.listen(port, () => log.info({ port }, "order started"));
}

function gateway() {
  const app = base("gateway");
  async function forward(req, res, url) {
    const response = await request(url, {
      method: req.method,
      headers: { "content-type": "application/json", "x-request-id": req.requestId },
      body: req.method === "GET" ? undefined : JSON.stringify(req.body),
    });
    res.status(response.statusCode).send(await response.body.text());
  }
  app.post("/orders", (req, res) => forward(req, res, `${process.env.ORDER_URL}/orders`));
  app.get("/inventory/:sku", (req, res) => forward(req, res, `${process.env.INVENTORY_URL}/inventory/${encodeURIComponent(req.params.sku)}`));
  app.listen(port, () => log.info({ port }, "gateway started"));
}

if (service === "inventory") inventory();
else if (service === "order") await order();
else if (service === "gateway") gateway();
docker compose up
curl http://localhost:8080/inventory/sku-1
curl -X POST http://localhost:8080/orders -H "content-type: application/json" -d '{"customerId":"cust-1","items":[{"sku":"sku-1","quantity":2}]}'
docker compose down

Critères Avant Production

Avant de publier, ne comptez pas seulement le nombre de services. Vérifiez si chaque service peut être modifié, testé, déployé et restauré sans bloquer tout le produit. Demandez à Claude Code de transformer un flux métier en tableau avec propriétaire des données, contrat API, test de contrat, métrique clé et rollback.

Observabilité, Tests Et Rollout

Le minimum viable comprend x-request-id, logs structurés, nom de service, IDs métier, /health, taux d’erreur et latence. Demandez à Claude Code de relire la compatibilité API, les migrations par service, l’absence de logique métier dans la gateway, les branches 400/409/500, la panne Redis, les Feature Flags, le canary et le rollback.

Les bons cas d’usage sont l’e-commerce avec commande, stock, paiement et notification, le SaaS B2B avec facturation, permissions et audit, et les plateformes média avec ingestion, transformation, recherche et diffusion. Les pièges fréquents sont le découpage par tables, la base partagée, une bibliothèque domaine commune trop grosse, la logique métier dans la gateway et un déploiement sans observabilité.

Le vrai use case est une capacité métier qui change, monte en charge ou échoue différemment du reste du produit. Le pitfall classique est de créer des services sans propriétaire clair. Demandez à Claude Code une fiche courte par service candidat: owner, contrat API, tables possédées, événements produits, événements consommés, dashboard, SLO, commande de déploiement, commande de rollback et comportement quand une dépendance tombe.

Ajoutez aussi l’impact business. Si le service touche le checkout, l’inscription d’essai, les emails, les publicités, les rapports ou les formulaires de consultation, la checklist doit vérifier ce chemin. Une séparation propre sur le papier mais qui casse l’attribution ou les notifications reste une mauvaise décision. Pour un premier PR, un inventaire de services et un test de contrat valent souvent mieux que dix dossiers générés.

Si vous voulez réutiliser des extraits CLAUDE.md, des checklists de review et des modèles de contrats API, commencez par les produits pratiques ClaudeCodeLab.

Pour faire relire les frontières, contrats API, Compose et monitoring d’un vrai projet, l’équipe peut commencer par Claude Code training and consultation sur un seul flux métier.

#Claude Code #microservices #API design #Docker Compose #observabilité #tests
Gratuit

PDF gratuit: cheatsheet Claude Code

Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.

Nous protégeons vos données et n'envoyons pas de spam.

Masa

À propos de l'auteur

Masa

Ingénieur spécialisé dans les workflows pratiques avec Claude Code.