Patterns
Circuit breaker (closed / open / half-open)
Protection contre les pannes en cascade des dépendances API
Le circuit breaker isole les appels vers une dépendance défaillante (SuperPDP, BulkGate SMS, partenaire de signature certifié eIDAS) pour éviter qu'une panne externe ne propage des timeouts à toute l'application. Trois états. CLOSED (nominal) : les appels passent normalement, on compte les échecs sur fenêtre glissante. Au-delà du seuil (ex: 50% d'échecs sur 20 appels), le breaker passe OPEN : tous les appels échouent immédiatement (fail fast) sans toucher la dépendance, pendant un cooldown (ex: 30s). Après cooldown, état HALF-OPEN : N appels de test sont laissés passer ; s'ils réussissent, retour CLOSED ; sinon, retour OPEN avec cooldown doublé. Patterns implémentations : `opossum` (Node.js), `resilience4j` (Java), middleware custom Laravel. Métriques exposées à Datadog/Sentry pour alerter sur les transitions OPEN.
À retenir
- 3 états : CLOSED (nominal), OPEN (fail-fast), HALF-OPEN (probing)
- Seuil typique : 50% échecs sur 20 appels → OPEN
- Cooldown initial 30s, doublé à chaque retour OPEN (max 5 min)
- Métrique critique : taux de transitions OPEN par minute
- Libs : opossum (JS), resilience4j (Java), middleware Laravel custom
Exemple de code
import CircuitBreaker from 'opossum';
const superpdpCall = async (payload: unknown) =>
fetch('https://api.superpdp.fr/v1.beta/invoices', {
method: 'POST',
body: JSON.stringify(payload),
}).then(r => r.json());
const breaker = new CircuitBreaker(superpdpCall, {
timeout: 5000, // ms
errorThresholdPercentage: 50,
resetTimeout: 30_000, // 30s cooldown
rollingCountTimeout: 60_000,
rollingCountBuckets: 10,
});
breaker.on('open', () => metrics.incr('superpdp.breaker.open'));
breaker.on('halfOpen', () => metrics.incr('superpdp.breaker.halfopen'));
breaker.fallback(() => ({ status: 'queued_for_retry' }));