Cinq erreurs d'intégration d'API critiques au démarrage
Erreur n ° 1. Pas d'idempotence et « tempête » des rétrogrades
Symptômes : prises de commandes/paiements, écarts de montants, retours controversés, alertes DLQ en hausse.
Racine : refaire les requêtes/webhooks et les flapps réseau sont normaux. Si l'opération « créer/débiter » n'est pas idempotente, les retraits multiplient les dégâts.
Quelle est la bonne chose à faire
Idempotency-Key/' opération _ id 'sur toutes les méthodes dangereuses (POST/PATCH).
Index unique dans la base de données par 'opération _ id'. Répétez - retournez le résultat précédent.
Webhooks via la table Inbox (dedupe par 'event _ id + signature'). Les événements sortants sont Outbox.
Retrai : 1 à 2 fois maximum, exposant + gitter, uniquement pour des opérations sécurisées.
Convention HTTP (exemple) :http
POST /v1/payments
Idempotency-Key: ik_f35a2
Content-Type: application/json
{"amount": 5000, "currency": "EUR", "source": "card_..."}sql
ALTER TABLE payments ADD CONSTRAINT uniq_op UNIQUE (operation_id);python for i in range(2):
try: return call_api(payload, timeout=0. 6)
except Timeout:
sleep(0. 05 2i + random. uniform(0, 0. 05))
raise UpstreamUnavailable- Toute la logique « monétaire/créatrice » a « opération _ id » et un indice uniq.
- Webhooks entrants uniquement via Inbox avec worker idempotent.
- Le SDK client affiche automatiquement Idempotency-Key.
Erreur n ° 2. Temporisation/rétroaction contre SLO : « surchauffe » des dépendances
Symptômes : p95 s'éloigne soudainement, les files d'attente grandissent, le circuit breaker « bouffe ».
Racine : le SLO total de la réponse est de 400 à 600 ms et les délais vers l'API externe sont de 1 à 2 s, et les retraits sont × 3. Vous faites plus longtemps que vous ne le pouvez et pilotez la dépendance avec des répétitions.
Quelle est la bonne chose à faire
Budget-temps : Si SLO 400 ms, upstream-time-out : 250-300 ms ; Délai total de la demande ≤ SLO.
Limites/Backpressure : sémaphores/worker-pool pour les appels à chaque dépendance. Plein → 429/503 immédiatement.
Circuit breaker : 'open' en time out/5xx, 'half-open' dosé.
Contrôle d'admission : limitez le parallélisme (par flux, par endpoint/PSP).
Exemple (Go) :go bou : = make (chan cadre {}, 64 )//limite de concurrence à PSP func callPSP (ctx context. Context, req Req) (Res, error) {
select {
case sem <- struct{}{}:
defer func(){ <-sem }()
c, cancel:= context. WithTimeout(ctx, 300time. Millisecond)
defer cancel()
return psp. Do(c, req)
default:
return Res {}, ErrBusy//échec immédiat au lieu d'une file d'attente sans fin
}
}- Les délais sont plus courts que SLO ; Retrai ≤ 2 ; il y a un gitter.
- Pools/sémaphores sur API externes ; circuit breaker avec métriques.
- Sur les itinéraires « busy », nous rendons les 429/Retry-After plutôt que de garder les connexions.
Erreur n ° 3. Sécurité faible : signatures de webhooks, secrets, TLS
Symptômes : les webhooks « étrangers » passent, les secrets dans le code/journal, les risques MITM.
Racine : pas de vérification de signature/fraîcheur, les secrets vivent dans les fichiers dev, les anciens TLS et les titres faibles.
Quelle est la bonne chose à faire
Signature des webhooks HMAC-SHA256 + « X-Timestamp » (fenêtre ≤ 5-10 min), comparaison rigoureuse de la signature.
mTLS pour les intégrations critiques ou IP allow-list.
Rotation des secrets via Vault/Cloud KMS ; un minimum de droits ; vérification de la soustraction.
TLS 1. 2/1. 3 only, HSTS, corrects CORS (liste étroite des sources).
Vérification de la signature (Python) :python def verify(sig_hdr, ts_hdr, body, secret):
if abs(time. time() - int(ts_hdr)) > 600: raise Expired()
calc = hmac. new(secret, (ts_hdr + "." + body). encode(), hashlib. sha256). hexdigest()
if not hmac. compare_digest(calc, sig_hdr): raise BadSig()- Tous les webhooks sont signés et vérifiés ; la fenêtre de fraîcheur est limitée.
- Secrets dans KMS/Vault, il y a rotation et audit.
- TLS/HSTS inclus ; CORS point ; IP/mTLS, le cas échéant.
Erreur n ° 4. Contrat-dérive : le schéma « a vécu sa vie »
Symptômes : le passage est tombé « seulement chez une partie des clients », 500/422 dans les logs, différentes versions du SDK et de l'API discutent.
Racine : il n'y a pas de description stricte des contrats, des changements incompatibles, des champs « silencieux », un sens différent pour les mêmes noms.
Quelle est la bonne chose à faire
Premier contrat : OpenAPI/AsyncAPI + génération de serveurs/clients ; pour les événements - Avro/Protobuf + Schema Registry.
Versioning : 'v1 → v2' (URI/header), deprecation-plan, grace-période.
Backward-compat : seulement les modifications additives dans les versions mineures ; interdiction de supprimer/renommer sans v-bump.
Tests contractuels : Pact/Buf - le fournisseur/consumer est vérifié par CI.
Exemples :yaml
OpenAPI : type clair de somme en unités mineures amount_minor :
type : integer minimum : 0 description : Montant en unités minimales de devise (entier)- Les contrats sont stockés dans git, CI valide/casse en cas d'incompatibilité.
- Registres de schémas d'événements, compatibilité « back/forward ».
- Page d'accueil des modifications, dates de privation, banc d'essai pour les partenaires.
Erreur n ° 5. Lancement « aveugle » : pas de métriques/logs/remorques et bac à sable
Symptômes : « Rien n'est visible », le soutien s'effondre, le débage - avec les mains dans la vente.
Racine : n'ont pas inclus l'observabilité, pas de synthétiques, le bac à sable a été testé « sur les mots ».
Quelle est la bonne chose à faire
Métriques RED/USE : rate/error/latency sur chaque endpoint, par itinéraire/méthode.
Corrélation : 'trace _ id'dans tous les logs et réponses ; ligament de zapros↔vebkhuk.
Synthétique : échantillons de santé (login/deposit-sand), surveillance SLA T + 60 pour les webhooks.
Sandbox/stadge : clés/domaines complètement isolés, PSP fictifs, entrées « ne font pas partie des rapports ».
Réponse avec l'ID trace :http
HTTP/1. 1 202 Accepted
Trace-Id: 7f2b3d8e9c1a4
Location: /v1/ops/req_42/status- Métriques RED/USE, dashboards, alertes (symptômes + causes).
- Tracés de fin de mois ; logs JSON, sans PII, avec 'trace _ id'.
- Synthétiques des régions clés ; le bac à sable est obligatoire, les clés sont différentes.
Plan du prélude (T-7 → T-0)
T-7 jours :- Le contrat final : s'il n'y a pas de changement incompatible ; les schémas freeze.
- Secrets/certificats : vérifiez la rotation, les accès, les politiques KMS.
- Synthétique 24 × 7, les alertes sont attachées à l'appel.
- Mini-course de charge (burst 2-5 min) : p95/pools/files d'attente dans la zone verte.
- DRY-RUN webhooks (répétitions, 5xx, jitter), vérification DLQ.
- « Le livre des téléphones » des partenaires : contacts L1/L2, canal war-room.
- Trafic canalisé 5 % → 25 % → 50 % sur les gages SLO ; prêt rollback.
- Inclus kill-switch/feature-flags sur les fiches à risque.
- War-room est actif, les modèles de statut sont préparés.
Plan de rollback (si quelque chose a mal tourné)
1. Retirer le trafic sur la version/route stable précédente.
2. Désactiver les modifications controversées.
3. Stabiliser les files d'attente/pools, arrêter les retraits en cas de « tempête ».
4. Post-incident : collecter le temps, les racines, les tâches (fix-forward/fix de contrat).
Tableau d'auto-test de démarrage (court)
FAQ "Et si...
... le fournisseur ne prend pas en charge Idempotency-Key ?
Gardez 'hash (body)' + 'partner _ request _ id' et entrez votre idempotence.
... les webhooks arrivent parfois « avant » la réponse ?
Cochez "opération _ id'et gardez temporairement le statut" unknown → reconcile "; le reconciler périodique comblera les divergences.
... faut-il soutenir les anciens clients et les nouveaux ?
Versez endpoint's ('/v1 'et '/v2'), routez par titre/URI, gardez la compatibilité backward pendant au moins N mois.
Résumé
Les échecs des intégrations parlent presque toujours de la même chose : pas d'idempotence, mauvais délais et retraits, faible signature des webhooks, dérive des contrats et manque de visibilité. Fixez les contrats à l'avance, activez l'observation, placez les limites/becpresher, signez toutes les interactions extérieures et lancez le synthétiseur. Alors, même si les partenaires échouent, votre sortie restera gérable - sans argent perdu dans les retraits, et sans nuit blanche pour toute l'équipe.
