Manejo de Errores y Reintentos en la API de Didit con Go (ES)
Construir integraciones robustas con la API de Didit en Go exige estrategias sofisticadas de manejo de errores y reintentos. Esta guía explora las mejores prácticas, desde la comprensión de los límites de tasa y códigos de error.

Comprenda los límites de tasa de Didit Implemente la limitación del lado del cliente y el retroceso exponencial para las respuestas 429, utilizando los encabezados
X-RateLimit-Limit,X-RateLimit-RemainingyX-RateLimit-Resetpara evitar la interrupción del servicio.Diferencie los tipos de errores Distinga entre errores transitorios (por ejemplo, problemas de red, indisponibilidad del servicio) y errores permanentes (por ejemplo, claves de API inválidas, solicitudes mal formadas) para aplicar una lógica de reintento adecuada o fallar rápidamente.
Implemente mecanismos de reintento robustos Emplee bucles de reintento estructurados con retroceso exponencial, fluctuación y un número máximo de intentos de reintento para manejar fallas transitorias de manera elegante, mejorando la confiabilidad de operaciones críticas como la creación de sesiones.
El enfoque "Developer-First" de Didit simplifica la integración Didit proporciona documentación clara de la API, encabezados específicos de límite de tasa y una arquitectura modular, lo que permite a los desarrolladores de Go construir flujos de verificación de identidad resilientes con facilidad y confianza.
La integración de APIs de terceros es una piedra angular del desarrollo de aplicaciones modernas, y la verificación de identidad no es una excepción. Al trabajar con servicios críticos como la plataforma de identidad de Didit, es fundamental garantizar que su integración sea resistente a las fluctuaciones de la red, los problemas del servicio y los límites de tasa. Esta guía profundiza en las estrategias avanzadas de manejo de errores y reintentos específicamente adaptadas para integraciones de la API de Didit utilizando Go, lo que le ayudará a construir sistemas robustos y confiables.
Comprensión del Panorama de Errores de la API de Didit
Antes de implementar cualquier lógica de reintento, es crucial comprender los tipos de errores que puede encontrar. La API de Didit, como muchos servicios bien diseñados, comunica varios estados a través de códigos de estado HTTP. Si bien los códigos 2xx estándar indican éxito, se centrará principalmente en 4xx (errores del cliente) y 5xx (errores del servidor), y especialmente en 429 (Demasiadas solicitudes).
La Limitación de Tasa de Didit y lo que Significa para Usted
Didit aplica limitación de tasa para mantener la estabilidad de la API. Este es un aspecto crítico a gestionar en su integración. Por ejemplo, los puntos finales GET suelen tener un límite global de 300 solicitudes por minuto por aplicación, con puntos finales específicos como session-decision (100 rpm) o session-v2-create (600 rpm) que tienen sus propios límites, potencialmente más estrictos. Cuando alcanza un límite de tasa, Didit responde con un código de estado 429 Too Many Requests e incluye encabezados útiles:
X-RateLimit-Limit: El número máximo de solicitudes permitidas en la ventana actual.X-RateLimit-Remaining: El número de solicitudes restantes en la ventana actual.X-RateLimit-Reset: El tiempo (en segundos de época) cuando se restablece la ventana de límite de tasa actual.Retry-After: (A menudo incluido) El número de segundos que debe esperar antes de realizar otra solicitud.
Su cliente Go debe monitorear activamente estos encabezados. Cuando X-RateLimit-Remaining cae por debajo de un cierto umbral (por ejemplo, el 15% de X-RateLimit-Limit), debe limitar proactivamente sus solicitudes. Ignorar esto puede llevar a errores 429 sostenidos, lo que afectará la capacidad de su aplicación para crear sesiones de verificación o recuperar resultados de productos como la verificación de identidad o el cribado AML de Didit.
Implementación de Estrategias de Reintento Robustas con Retroceso Exponencial en Go
Para errores transitorios (por ejemplo, tiempos de espera de red, indisponibilidad temporal del servicio o 429s), los reintentos son esenciales. Sin embargo, los reintentos ingenuos pueden exacerbar los problemas. El estándar de oro es el retroceso exponencial con fluctuación.
Retroceso Exponencial con Fluctuación
El retroceso exponencial significa aumentar el tiempo de espera entre reintentos de forma exponencial. La fluctuación (añadir un pequeño retraso aleatorio) evita un problema de 'estampida' en el que muchos clientes reintentan simultáneamente después de una interrupción, sobrecargando el servicio nuevamente. Aquí hay un ejemplo conceptual de Go:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"time"
"math/rand"
)
func callDiditAPIWithRetry(url string, maxRetries int) ([]byte, error) {
client := &http.Client{Timeout: 10 * time.Second}
rand.Seed(time.Now().UnixNano())
for i := 0; i <= maxRetries; i++ {
resp, err := client.Get(url)
if err != nil {
// Manejar errores de red (ej. conexión rechazada, timeout)
fmt.Printf("Intento %d: Error de red: %v\n", i+1, err)
if i == maxRetries {
return nil, fmt.Errorf("falló después de %d reintentos: %w", maxRetries, err)
}
sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond // Retroceso exponencial + fluctuación
fmt.Printf("Reintentando en %v...\n", sleepTime)
time.Sleep(sleepTime)
continue
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK:
fmt.Printf("Intento %d: ¡Éxito!\n", i+1)
return ioutil.ReadAll(resp.Body)
case http.StatusTooManyRequests:
// Respetar el encabezado Retry-After si está presente
retryAfter := resp.Header.Get("Retry-After")
if retryAfter != "" {
if sleepSeconds, err := time.ParseDuration(retryAfter + "s"); err == nil {
fmt.Printf("Intento %d: Límite de tasa alcanzado. Reintentando después de %v.\n", i+1, sleepSeconds)
time.Sleep(sleepSeconds)
continue
}
}
// Retroceder al retroceso exponencial si Retry-After falta o es inválido
fmt.Printf("Intento %d: Límite de tasa alcanzado (429).\n", i+1)
if i == maxRetries {
return nil, fmt.Errorf("límite de tasa alcanzado después de %d reintentos", maxRetries)
}
sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond
fmt.Printf("Reintentando en %v...\n", sleepTime)
time.Sleep(sleepTime)
continue
case http.StatusInternalServerError, http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout:
// Errores del lado del servidor que pueden ser transitorios
fmt.Printf("Intento %d: Error del servidor %d. Reintentando.\n", i+1, resp.StatusCode)
if i == maxRetries {
return nil, fmt.Errorf("error del servidor %d después de %d reintentos", resp.StatusCode, maxRetries)
}
sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond
fmt.Printf("Reintentando en %v...\n", sleepTime)
time.Sleep(sleepTime)
continue
default:
// Errores no reintentables (errores de cliente 4xx, etc.)
body, _ := ioutil.ReadAll(resp.Body)
return nil, fmt.Errorf("error de API no reintentable: %d %s, respuesta: %s", resp.StatusCode, resp.Status, string(body))
}
}
return nil, fmt.Errorf("flujo de control inesperado") // No debería alcanzarse
}
func main() {
// Ejemplo de uso: Reemplazar con el punto final real de la API de Didit
// Para una integración real, estaría POSTeando a /v3/session/ o similar
// y manejando la verification_url.
apiURL := "https://verification.didit.me/health"
data, err := callDiditAPIWithRetry(apiURL, 5)
if err != nil {
fmt.Println("Fallo al llamar a la API:", err)
} else {
fmt.Println("Respuesta de la API:", string(data))
}
}
Este fragmento demuestra cómo manejar errores de red, 429s (respetando Retry-After) y errores comunes 5xx con retroceso exponencial y fluctuación. También muestra cómo fallar rápidamente para errores 4xx no reintentables, que suelen deberse a una entrada incorrecta y no se resolverán al reintentar. Esto es crucial para operaciones como la creación de una sesión de verificación utilizando la arquitectura modular de Didit.
Implementación de un Patrón de Disyuntor
Si bien los reintentos ayudan con problemas transitorios, reintentar continuamente un servicio fallido puede sobrecargarlo aún más o desperdiciar recursos si el servicio está realmente caído. Aquí es donde entra en juego el patrón de disyuntor. Un disyuntor monitorea las fallas y, si alcanzan un cierto umbral, "abre" el circuito, evitando más solicitudes durante un período establecido. Después de este período, permite algunas solicitudes de prueba para ver si el servicio se ha recuperado.
En Go, puede usar bibliotecas como sony/gobreaker para implementar este patrón:
package main
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/sony/gobreaker"
)
var cb *gobreaker.CircuitBreaker
func init() {
st := gobreaker.Settings{
Name: "DiditAPICircuitBreaker",
MaxRequests: 3, // Permitir 3 solicitudes en estado semiabierto
Interval: 5 * time.Second, // Período para recopilar datos para decisiones de viaje
Timeout: 10 * time.Second, // Abrir el circuito durante 10 segundos
ReadyToTrip: func(counts gobreaker.Counts) bool {
return counts.ConsecutiveFailures > 5 // Abrir el circuito después de 5 fallas consecutivas
},
OnStateChange: func(name string, from gobreaker.State, to gobreaker.State) {
fmt.Printf("El disyuntor '%s' cambió de %s a %s\n", name, from, to)
},
}
cb = gobreaker.NewCircuitBreaker(st)
}
func callDiditAPIWithCircuitBreaker(url string) ([]byte, error) {
body, err := cb.Execute(func() (interface{}, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err // Error de red
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
// Solo contar 5xx y 429 como fallas para el disyuntor
if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= http.StatusInternalServerError {
return nil, fmt.Errorf("La API devolvió el estado %d", resp.StatusCode)
}
// Para otros errores 4xx, es posible que no queramos abrir el disyuntor, pero aún así devolver un error
bodyBytes, _ := ioutil.ReadAll(resp.Body)
return nil, fmt.Errorf("error de API no reintentable: %d %s, respuesta: %s", resp.StatusCode, resp.Status, string(bodyBytes))
}
return ioutil.ReadAll(resp.Body)
})
if err != nil {
if errors.Is(err, gobreaker.ErrOpenState) {
return nil, fmt.Errorf("el disyuntor está abierto: %w", err)
}
return nil, err
}
return body.([]byte), nil
}
func main() {
// Ejemplo de uso
apiURL := "https://verification.didit.me/health"
for i := 0; i < 10; i++ {
data, err := callDiditAPIWithCircuitBreaker(apiURL)
if err != nil {
fmt.Printf("La llamada %d falló: %v\n", i+1, err)
} else {
fmt.Printf("La llamada %d fue exitosa: %s\n", i+1, string(data))
}
time.Sleep(1 * time.Second)
}
}
La combinación de disyuntores con retroceso exponencial garantiza que su aplicación siga siendo receptiva y no sobrecargue un servicio externo con problemas. Esto es particularmente importante cuando se trata de solicitudes de verificación de identidad de gran volumen, como las que involucran la verificación de identidad de Didit o las comprobaciones de vivacidad pasiva y activa.
Manejo de Fallas de Webhook y Resultados Asincrónicos
La API de Didit a menudo proporciona resultados de forma asincrónica a través de webhooks, por ejemplo, después de que un usuario completa un flujo de verificación de identidad o cuando finaliza una verificación de AML. Su punto final de webhook debe ser robusto. Si su punto final no procesa un webhook (por ejemplo, devuelve un código de estado 5xx), Didit intentará reenviar el webhook. Es crucial:
- Reconocimiento inmediato de la recepción: Devuelva un código de estado 2xx lo más rápido posible para indicar la recepción exitosa, incluso si el procesamiento lleva más tiempo.
- Procesar asincrónicamente: Entregue la carga útil del webhook a un trabajador en segundo plano o a una cola de mensajes (por ejemplo, Kafka, RabbitMQ) para su procesamiento. Esto evita que su punto final de webhook agote el tiempo de espera de los reintentos de Didit.
- Idempotencia: Asegúrese de que su lógica de procesamiento de webhook sea idempotente. Si Didit reintenta y entrega el mismo webhook varias veces, su sistema debe procesarlo solo una vez para evitar acciones duplicadas o inconsistencias de datos.
- Verificar firmas: Siempre verifique la firma del webhook utilizando su
Webhook Secret Keyde la Consola de Didit para asegurarse de que la solicitud realmente se originó en Didit y no ha sido manipulada.
Cómo Ayuda Didit
Didit está diseñado pensando en la experiencia del desarrollador y la confiabilidad, proporcionando características que simplifican inherentemente el manejo avanzado de errores y las estrategias de reintento para sus integraciones de Go. Nuestro enfoque "developer-first" significa una documentación de API clara y completa, un sandbox instantáneo y APIs limpias que facilitan la integración.
- Limitación de tasa predecible: Didit define claramente los límites de tasa globales y específicos de los puntos finales, junto con los encabezados HTTP estándar (
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset,Retry-After) para guiar su lógica de limitación del lado del cliente y retroceso. Esta transparencia le permite construir mecanismos de reintento optimizados para servicios como la verificación de identidad y el cribado AML. - Arquitectura modular: Nuestras primitivas de identidad modulares significan que puede construir flujos de trabajo que son resilientes por diseño. Si una verificación específica (por ejemplo, prueba de domicilio) encuentra un problema transitorio, su flujo de trabajo general puede configurarse para adaptar o reintentar componentes específicos sin afectar los pasos de verificación no relacionados.
- Confiabilidad nativa de IA: El backend nativo de IA de Didit está construido para la escala y la resiliencia, minimizando los errores del lado del servidor que encontrará. Esto le permite centrar su manejo de errores en problemas de red y del lado del cliente, en lugar de interrupciones constantes del servicio.
- KYC Core Gratuito y Precios Flexibles: Comience con el nivel gratuito de Didit para KYC Core, lo que le permite probar a fondo su manejo de errores y estrategias de reintento en un entorno similar a la producción sin costos iniciales. Nuestro modelo de pago por verificación exitosa alinea aún más nuestro éxito con el suyo.
¿Listo para empezar?
¿Listo para ver Didit en acción? Obtenga una demostración gratuita hoy mismo.
Comience a verificar identidades de forma gratuita con el nivel gratuito de Didit.