Cinco errores críticos de integración de API al iniciar
Error # 1. No hay idempotencia y «tormenta» de retraídos
Síntomas: las tomas de pedidos/pagos, las cantidades divergentes, las devoluciones controvertidas, las alertas de DLQ están creciendo.
Raíz: reenviar consultas/webhooks y flappies de red son normales. Si la operación «crear/cargar» no es idempotente, los retratos multiplican los daños.
Cómo es correcto
Idempotency-Key/' operation _ id 'a todos los métodos inseguros (POST/PATCH).
Índice único en la DB por 'operation _ id'. Repetición - devuelva el resultado pasado.
Webhooks a través de la tabla Inbox (dedupe por 'event _ id + signature'). Eventos salientes - Outbox.
Retraídas: máximo 1-2 veces, expositor + jitter, solo para operaciones seguras.
Convención HTTP (ejemplo):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- Toda la lógica «monetaria/creadora» tiene un 'operation _ id' y un índice uniq.
- Los webhooks entrantes son sólo a través de Inbox con un worker idempotente.
- El SDK del cliente coloca automáticamente Idempotency-Key.
Error # 2. Tiempos de espera/retiros contra SLO: «sobrecalentamiento» de dependencias
Síntomas: p95 de repente está flotando, las colas están creciendo, circuit breaker «chillando».
Raíz: la respuesta SLO total es de 400-600 ms, y los tiempos de espera a las API externas son de 1-2 s, y aún así retraen × 3. Haces más de lo que puedes y asaltas la adicción con repeticiones.
Cómo es correcto
Budget-timing: si SLO 400 ms, upstream-time-out: 250-300 ms; tiempo de espera total de la solicitud ≤ SLO.
Limits/Backpressure: semáforos/worker-pool para llamadas a cada dependencia. Desbordado → 429/503 inmediatamente.
Circuito breaker: 'open' en tiempos de espera/5xx, 'half-open' dosificado.
Control de administración: limite el paralelismo (por hilo, por endpoint/PSP).
Ejemplo (Go):go sem: = make (chan stract {}, 64 )//límite de competencia a 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//fallo inmediato en lugar de cola sin fin
}
}- Los tiempos de espera son más cortos que SLO; Retraídas ≤ 2; hay un jitter.
- Grupos/semáforos en API externas; circuito breaker con métricas.
- En las rutas «busy», devolvemos 429/Retry-After, no mantenemos conexiones.
Error # 3. Seguridad débil: firmas de webhooks, secretos, TLS
Síntomas: los webhooks «ajenos» desaparecen, secretos en el código/login, riesgos MITM.
Raíz: sin verificación de firma/frescura, los secretos viven en archivos env, viejos TLS y títulos débiles.
Cómo es correcto
Firma de webhooks HMAC-SHA256 + 'X-Timestamp' (ventana ≤ 5-10 min), comparación estricta de la firma.
mTLS para integraciones críticas o IP allow-list.
La rotación de secretos a través de Vault/Cloud KMS; un mínimo de derechos; auditoría de la sustracción.
TLS 1. 2/1. 3 solamente, HSTS, CORS correctos (lista estrecha de fuentes).
Verificación de firma (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()- Todos los webhooks están firmados y verificados; la ventana de frescura es limitada.
- Secretos en KMS/Vault, hay rotación y auditoría.
- TLS/HSTS incluidos; CORS punto; IP/mTLS cuando corresponda.
Error número 4. Contrato de deriva: el esquema «vivió su vida»
Síntomas: el prod cayó «sólo en una parte de los clientes», 500/422 en los logs, diferentes versiones de SDK y API discuten.
Raíz: no hay una descripción estricta de los contratos, reversa cambios incompatibles, campos «silenciosos», diferente significado en los mismos nombres.
Cómo es correcto
Contrato-primero: OpenAPI/AsyncAPI + generación de servidores/clientes; para eventos - Avro/Protobuf + Registro de Schema.
Versioning: 'v1 → v2' (URI/header), deprecation-plan, período grace.
Backward-compat: sólo cambios additive en lanzamientos menores; prohibición de eliminar/cambiar el nombre sin v-bump.
Pruebas contractuales: Aprox/Buf - el proveedor/consumer se comprueba en CI.
Ejemplos:yaml
OpenAPI: tipo claro de suma en unidades menores amount_minor:
tipo: integer minimum: 0 description: Suma en unidades mínimas de moneda (entero)- Los contratos se mantienen en git, CI valida/rompe en incompatibilidad.
- Registros de esquemas para eventos, compatibilidad «back/forward».
- La página de cambios, las fechas de la privación, el banco de pruebas para los socios.
Error # 5. Lanzamiento «ciego»: sin métricas/registros/tracks y sandbox
Síntomas: «no se ve nada», el apoyo se inunda, debag con las manos en la venta.
Raíz: no se incluyó la observabilidad, no hay sintética, la caja de arena se probó «en palabras».
Cómo es correcto
Métricas RED/USE: rate/error/latency en cada endpoint, por rutas/métodos.
Correlación: 'trace _ id' en todos los logs y respuestas; el ligamento zapros↔vebkhuk.
Sintética: muestras de salud (login/deposite-arena), monitoreo SLA T + 60 para webhooks.
Sandbox/stage: claves/dominios completamente aislados, PSP ficticios, las entradas «no caen en los informes».
Respuesta con identificador trace:http
HTTP/1. 1 202 Accepted
Trace-Id: 7f2b3d8e9c1a4
Location: /v1/ops/req_42/status- Métricas de RED/USE, dashboards, alertas (síntomas + causas).
- Senderos de fin a fin; los registros JSON, sin PII, con 'trace _ id'.
- Sintética de regiones clave; sandbox es obligatorio, las llaves son diferentes.
Plan Prelaunch (T-7 → T-0)
T-7 días:- Contrato de escaneo final: si no hay cambios incompatibles; freeze esquemas.
- Secretos/certificados: compruebe la rotación, los accesos, las políticas KMS.
- Sintética 24 × 7, alertas atadas al on-call.
- Mini carrera de carga (burst 2-5 min): p95/pools/colas en zona verde.
- DRY-RUN webhooks (repeticiones, 5xx, jitter), verificación DLQ.
- El «libro de teléfonos» de los socios: contactos L1/L2, canal de guerra-habitación.
- Tráfico canario 5% → 25% → 50% en las puertas SLO; listo para el rollback.
- Incluye kill-switch/feature-flags en fichas de riesgo.
- War-room está activo, las plantillas de estado están preparadas.
Plan Rollback (si algo salió mal)
1. Retire el tráfico a la versión/ruta estable anterior.
2. Desactivar los cambios controvertidos con fichflag.
3. Estabilizar las colas/piscinas, detener los retratos en una «tormenta».
4. Post-incidente: recoger la línea de tiempo, las raíces, las tareas (fix-forward/fixes del contrato).
Tabla de autoexamen para inicio (corto)
FAQ «¿y qué pasa si...»
... ¿el proveedor no admite Idempotency-Key?
Almacena 'hash (body)' + 'partner _ request _ id' e introduce tu idempotencia.
... ¿los webhooks a veces vienen «antes» de la respuesta?
Coser en 'operation _ id' y mantener temporalmente 'unknown → reconcile' estado; reconciler periódico cerrará las discrepancias.
... ¿hay que apoyar a los viejos clientes y a los nuevos?
Versionar el endpoint's ('/v1 'y '/v2'), enrutar el encabezado/URI, mantener la compatibilidad con backward durante un mínimo de N meses.
Resumen
Los fallos de las integraciones son casi siempre sobre lo mismo: no hay idempotencia, tiempos de espera y retratos irregulares, firma débil de webhooks, deriva de contratos y falta de visibilidad. Fije los contratos con antelación, incluya la observabilidad, coloque los límites/backpresher, firme todas las interacciones externas y ejecute la sintética. Entonces, incluso si los socios fallan, su lanzamiento seguirá siendo manejable, sin dinero perdido en retiros y sin noche de insomnio en todo el equipo.
