Gestão de Erros e Estratégias de Repetição da API Didit em Go (PT-PT)
Construir integrações robustas com a API Didit em Go exige gestão de erros e estratégias de repetição sofisticadas. Este guia explora as melhores práticas, desde a compreensão dos limites de taxa da Didit e códigos de erro.

Compreenda os Limites de Taxa da DiditImplemente a limitação do lado do cliente e o 'exponential backoff' para respostas 429, utilizando os cabeçalhos
X-RateLimit-Limit,X-RateLimit-RemainingeX-RateLimit-Resetpara evitar a interrupção do serviço.Diferencie os Tipos de ErroDistinguir entre erros transitórios (por exemplo, problemas de rede, indisponibilidade do serviço) e erros permanentes (por exemplo, chaves de API inválidas, pedidos malformados) para aplicar a lógica de repetição apropriada ou falhar rapidamente.
Implemente Mecanismos de Repetição RobustosEmpregue ciclos de repetição estruturados com 'exponential backoff', 'jitter' e um número máximo de tentativas para lidar com falhas transitórias de forma graciosa, melhorando a fiabilidade de operações críticas como a criação de sessões.
A Abordagem 'Developer-First' da Didit Simplifica a IntegraçãoA Didit fornece documentação de API clara, cabeçalhos de limite de taxa específicos e uma arquitetura modular, permitindo que os programadores Go construam fluxos de verificação de identidade resilientes com facilidade e confiança.
A integração de APIs de terceiros é um pilar do desenvolvimento de aplicações modernas, e a verificação de identidade não é exceção. Ao trabalhar com serviços críticos como a plataforma de identidade da Didit, é fundamental garantir que a sua integração seja resiliente a flutuações de rede, interrupções de serviço e limites de taxa. Este guia aprofunda-se em estratégias avançadas de gestão de erros e repetição especificamente adaptadas para integrações da API Didit usando Go, ajudando-o a construir sistemas robustos e fiáveis.
Compreender o Cenário de Erros da API Didit
Antes de implementar qualquer lógica de repetição, é crucial entender os tipos de erros que pode encontrar. A API da Didit, como muitos serviços bem desenhados, comunica vários estados através de códigos de estado HTTP. Embora os códigos 2xx padrão indiquem sucesso, irá focar-se principalmente nos 4xx (erros do cliente) e 5xx (erros do servidor), e especialmente no 429 (Demasiados Pedidos).
Limitação de Taxa da Didit e o Que Significa Para Si
A Didit impõe limitação de taxa para manter a estabilidade da API. Este é um aspeto crítico a gerir na sua integração. Por exemplo, os 'endpoints' GET tipicamente têm um limite global de 300 pedidos por minuto por aplicação, com 'endpoints' específicos como session-decision (100 rpm) ou session-v2-create (600 rpm) a terem os seus próprios limites, potencialmente mais rigorosos. Quando atinge um limite de taxa, a Didit responde com um código de estado 429 Too Many Requests e inclui cabeçalhos úteis:
X-RateLimit-Limit: O número máximo de pedidos permitidos na janela atual.X-RateLimit-Remaining: O número de pedidos restantes na janela atual.X-RateLimit-Reset: O tempo (em segundos de época) quando a janela de limite de taxa atual é reiniciada.Retry-After: (Frequentemente incluído) O número de segundos a esperar antes de fazer outro pedido.
O seu cliente Go deve monitorizar ativamente estes cabeçalhos. Quando X-RateLimit-Remaining cai abaixo de um certo limiar (por exemplo, 15% de X-RateLimit-Limit), deve limitar proativamente os seus pedidos. Ignorar estes pode levar a erros 429 sustentados, afetando a capacidade da sua aplicação para criar sessões de verificação ou recuperar resultados de produtos como a Verificação de ID ou o Rastreio AML da Didit.
Implementar Estratégias de Repetição Robustas com 'Exponential Backoff' em Go
Para erros transitórios (por exemplo, 'timeouts' de rede, indisponibilidade temporária do serviço, ou 429s), as repetições são essenciais. No entanto, repetições ingénuas podem exacerbar problemas. O padrão ouro é o 'exponential backoff' com 'jitter'.
'Exponential Backoff' com 'Jitter'
'Exponential backoff' significa aumentar o tempo de espera entre as repetições exponencialmente. 'Jitter' (adicionar um pequeno atraso aleatório) evita um problema de 'thundering herd' onde muitos clientes tentam novamente simultaneamente após uma interrupção, sobrecarregando o serviço novamente. Aqui está um exemplo conceptual em 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 {
// Lidar com erros de rede (por exemplo, ligação recusada, timeout)
fmt.Printf("Tentativa %d: Erro de rede: %v\n", i+1, err)
if i == maxRetries {
return nil, fmt.Errorf("falha após %d repetições: %w", maxRetries, err)
}
sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond // Exponential backoff + jitter
fmt.Printf("A tentar novamente em %v...\n", sleepTime)
time.Sleep(sleepTime)
continue
}
defer resp.Body.Close()
switch resp.StatusCode {
case http.StatusOK:
fmt.Printf("Tentativa %d: Sucesso!\n", i+1)
return ioutil.ReadAll(resp.Body)
case http.StatusTooManyRequests:
// Respeitar o cabeçalho Retry-After se presente
retryAfter := resp.Header.Get("Retry-After")
if retryAfter != "" {
if sleepSeconds, err := time.ParseDuration(retryAfter + "s"); err == nil {
fmt.Printf("Tentativa %d: Limite de taxa atingido. A tentar novamente após %v.\n", i+1, sleepSeconds)
time.Sleep(sleepSeconds)
continue
}
}
// Recorrer ao exponential backoff se Retry-After estiver em falta ou for inválido
fmt.Printf("Tentativa %d: Limite de taxa atingido (429).\n", i+1)
if i == maxRetries {
return nil, fmt.Errorf("limite de taxa atingido após %d repetições", maxRetries)
}
sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond
fmt.Printf("A tentar novamente em %v...\n", sleepTime)
time.Sleep(sleepTime)
continue
case http.StatusInternalServerError, http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout:
// Erros do lado do servidor que podem ser transitórios
fmt.Printf("Tentativa %d: Erro do servidor %d. A tentar novamente.\n", i+1, resp.StatusCode)
if i == maxRetries {
return nil, fmt.Errorf("erro do servidor %d após %d repetições", resp.StatusCode, maxRetries)
}
sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond
fmt.Printf("A tentar novamente em %v...\n", sleepTime)
time.Sleep(sleepTime)
continue
default:
// Erros não repetíveis (erros do cliente 4xx, etc.)
body, _ := ioutil.ReadAll(resp.Body)
return nil, fmt.Errorf("erro de API não repetível: %d %s, resposta: %s", resp.StatusCode, resp.Status, string(body))
}
}
return nil, fmt.Errorf("fluxo de controlo inesperado") // Não deve ser alcançado
}
func main() {
// Exemplo de uso: Substitua pelo endpoint real da API Didit
// Para uma integração real, estaria a POSTar para /v3/session/ ou similar
// e a lidar com o verification_url.
apiURL := "https://verification.didit.me/health"
data, err := callDiditAPIWithRetry(apiURL, 5)
if err != nil {
fmt.Println("Falha ao chamar a API:", err)
} else {
fmt.Println("Resposta da API:", string(data))
}
}
Este excerto demonstra como lidar com erros de rede, 429s (respeitando o Retry-After), e erros 5xx comuns com 'exponential backoff' e 'jitter'. Também mostra como falhar rapidamente para erros 4xx não repetíveis, que são tipicamente devido a entrada incorreta e não se resolverão com a repetição. Isto é crucial para operações como a criação de uma sessão de verificação usando a arquitetura modular da Didit.
Implementar um Padrão de 'Circuit Breaker'
Embora as repetições ajudem com problemas transitórios, tentar continuamente um serviço com falhas pode sobrecarregá-lo ainda mais ou desperdiçar recursos se o serviço estiver verdadeiramente em baixo. É aqui que entra o padrão 'circuit breaker'. Um 'circuit breaker' monitoriza as falhas e, se estas atingirem um certo limiar, "abre" o circuito, impedindo mais pedidos durante um período definido. Após o período, permite alguns pedidos de teste para ver se o serviço recuperou.
Em Go, pode usar bibliotecas como sony/gobreaker para implementar este padrão:
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 pedidos em estado semiaberto
Interval: 5 * time.Second, // Período para recolher dados para decisões de disparo
Timeout: 10 * time.Second, // Abrir circuito por 10 segundos
ReadyToTrip: func(counts gobreaker.Counts) bool {
return counts.ConsecutiveFailures > 5 // Disparar após 5 falhas consecutivas
},
OnStateChange: func(name string, from gobreaker.State, to gobreaker.State) {
fmt.Printf("O Circuit Breaker '%s' mudou de %s para %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 // Erro de rede
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
// Contar apenas 5xx e 429 como falhas para o circuit breaker
if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= http.StatusInternalServerError {
return nil, fmt.Errorf("API devolveu estado %d", resp.StatusCode)
}
// Para outros erros 4xx, podemos não querer disparar o breaker, mas ainda assim devolver um erro
bodyBytes, _ := ioutil.ReadAll(resp.Body)
return nil, fmt.Errorf("erro de API não repetível: %d %s, resposta: %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("o circuit breaker está aberto: %w", err)
}
return nil, err
}
return body.([]byte), nil
}
func main() {
// Exemplo de uso
apiURL := "https://verification.didit.me/health"
for i := 0; i < 10; i++ {
data, err := callDiditAPIWithCircuitBreaker(apiURL)
if err != nil {
fmt.Printf("Chamada %d falhou: %v\n", i+1, err)
} else {
fmt.Printf("Chamada %d bem-sucedida: %s\n", i+1, string(data))
}
time.Sleep(1 * time.Second)
}
}
Combinar 'circuit breakers' com 'exponential backoff' garante que a sua aplicação permanece responsiva e não sobrecarrega um serviço externo em dificuldades. Isto é particularmente importante ao lidar com pedidos de verificação de identidade de alto volume, como aqueles que envolvem a Verificação de ID da Didit ou verificações de Vivacidade Passiva e Ativa.
Lidar com Falhas de Webhook e Resultados Assíncronos
A API da Didit frequentemente fornece resultados assincronamente via webhooks, por exemplo, depois de um utilizador completar um fluxo de verificação de ID ou quando uma verificação de Rastreio AML é concluída. O seu 'endpoint' de webhook deve ser robusto. Se o seu 'endpoint' falhar ao processar um webhook (por exemplo, devolve um código de estado 5xx), a Didit tentará novamente entregar o webhook. É crucial:
- Reconhecer a Receção Imediatamente: Devolver um código de estado 2xx o mais rapidamente possível para sinalizar a receção bem-sucedida, mesmo que o processamento demore mais.
- Processar Assincronamente: Entregar o 'payload' do webhook a um trabalhador de fundo ou fila de mensagens (por exemplo, Kafka, RabbitMQ) para processamento. Isto impede que o seu 'endpoint' de webhook faça 'timeout' das repetições da Didit.
- Idempotência: Garanta que a sua lógica de processamento de webhook é idempotente. Se a Didit tentar novamente e entregar o mesmo webhook várias vezes, o seu sistema deve processá-lo apenas uma vez para evitar ações duplicadas ou inconsistências de dados.
- Verificar Assinaturas: Verifique sempre a assinatura do webhook usando a sua
Webhook Secret Keyda Consola Didit para garantir que o pedido realmente se originou da Didit e não foi adulterado.
Como a Didit Ajuda
A Didit foi concebida com a experiência do programador e a fiabilidade em mente, fornecendo funcionalidades que simplificam inerentemente a gestão avançada de erros e estratégias de repetição para as suas integrações Go. A nossa abordagem 'developer-first' significa documentação de API clara e abrangente, um 'sandbox' instantâneo e APIs limpas que tornam a integração simples.
- Limitação de Taxa Previsível: A Didit define claramente limites de taxa globais e específicos de 'endpoint', juntamente com cabeçalhos HTTP padrão (
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset,Retry-After) para guiar a sua limitação do lado do cliente e lógica de 'backoff'. Esta transparência permite-lhe construir mecanismos de repetição otimizados para serviços como Verificação de ID e Rastreio AML. - Arquitetura Modular: Os nossos primitivos de identidade modulares significam que pode construir fluxos de trabalho que são resilientes por design. Se uma verificação específica (por exemplo, Prova de Morada) encontrar um problema transitório, o seu fluxo de trabalho geral pode ser configurado para adaptar ou tentar novamente componentes específicos sem afetar passos de verificação não relacionados.
- Fiabilidade Nativa de IA: O 'backend' nativo de IA da Didit é construído para escala e resiliência, minimizando os erros do lado do servidor que irá encontrar. Isto permite-lhe focar a sua gestão de erros em problemas de rede e do lado do cliente, em vez de interrupções constantes do serviço.
- KYC Básico Gratuito e Preços Flexíveis: Comece com o nível gratuito da Didit para KYC Básico, permitindo-lhe testar exaustivamente a sua gestão de erros e estratégias de repetição num ambiente de produção sem custos iniciais. O nosso modelo de pagamento por verificação bem-sucedida alinha ainda mais o nosso sucesso com o seu.
Pronto para Começar?
Pronto para ver a Didit em ação? Obtenha uma demonstração gratuita hoje.
Comece a verificar identidades gratuitamente com o nível gratuito da Didit.