Eventos
Gateway Fluid
Controle de Idempotência
22 min
o controle de idempotência no gateway fluid permite que você envie a mesma requisição múltiplas vezes de forma segura, garantindo que apenas uma execução será processada mesmo em casos de falhas de rede, timeouts ou tentativas acidentais de reenvio quando usar idempotência a idempotência é essencial em cenários onde é crítico evitar processamento duplicado pagamentos e transações financeiras criação de pedidos ou registros únicos integrações com sistemas externos que podem falhar webhooks que podem ser reenviados como funciona headers de request para usar idempotência, inclua o header x idempotency key em sua requisição ao gateway curl location '{gateway host}/{path}/{flow name}?key={api key}' \\ \ header 'content type application/json' \\ \ header 'x idempotency key pagamento usuario123 20240115' \\ \ data '{ "valor" 100 00, "usuario id" "123" }' formato da chave de idempotência tamanho entre 3 e 128 caracteres caracteres permitidos letras, números, hífen ( ), underscore ( ) e ponto ( ) recomendação use um identificador único e descritivo do contexto exemplos válidos pagamento 123 20240115 pedido usuario456 v2 webhook retry 001 chaves inválidas retornam erro 400 \# resposta para chave inválida http/1 1 400 bad request { "code" "400", "message" "invalid idempotency key invalid characters" } headers de response o gateway retorna informações sobre o status da idempotência x idempotency key pagamento usuario123 20240115 x idempotency status new status possíveis new primeira execução desta chave processing execução em andamento duplicate requisição duplicada (já processada) o controle de idempotência não verifica os detalhes da requisição (como o corpo) para identificar se já foi ou não processada esse controle é realizado exclusivamente pelo cabeçalho x idempotency key e x force retry ttl policies a política de tempo de vida do controle de idempotência segue a tabela abaixo status do fluxo ttl motivo sucesso | info 24h sucesso evitar reprocessamento erro | falha 5 min erro temporário retry rápido divergência 2h erro cliente evitar spam comportamento por tipo de execução de fluxo fluxos assíncronos (padrão) primeira requisição curl location '{gateway host}/v2/flows/processar pagamento?key={api key}' \\ \ header 'x idempotency key pag 123' \\ \ data '{"valor" 100}' \# resposta 200 ok \# headers \# x idempotency key pag 123 \# x idempotency status new { "event id" "evt abc123" } requisição duplicada \# mesma requisição enviada novamente curl location '{gateway host}/v2/flows/processar pagamento?key={api key}' \\ \ header 'x idempotency key pag 123' \\ \ data '{"valor" 100}' \# resposta 200 ok (mesmo event id) \# headers \# x idempotency key pag 123 \# x idempotency status duplicate { "event id" "evt abc123" } fluxos síncronos para fluxos síncronos, requisições duplicadas não retornam o resultado original curl location '{gateway host}/v2/flows/validar dados?sync=true\&key={api key}' \\ \ header 'x idempotency key validacao 456' \\ \ data '{"documento" "123456789"}' primeira execução http/1 1 200 ok x idempotency key validacao 456 x idempotency status new {"resultado" "documento valido"} execução duplicada http/1 1 200 ok x idempotency key validacao 456 x idempotency status duplicate (vazio) execução ainda processando http/1 1 200 ok x idempotency key validacao 456 x idempotency status processing (vazio) limitação atual para fluxos síncronos, requisições duplicadas retornam body vazio o resultado original não é cacheado, apenas os metadados da execução forçando nova execução force retry em casos onde você deseja reprocessar algum evento que já foi executado com uma chave de idempotência, use o header x force retry curl location '{gateway host}/v2/flows/processar pagamento?key={api key}' \\ \ header 'x idempotency key pag 123' \\ \ header 'x force retry true' \\ \ data '{"valor" 100}' códigos de status e erros status http todas as requisições com idempotência retornam 200 ok quando bem sucedidas, independentemente de ser uma execução nova ou duplicada a diferenciação é feita através dos headers erros comuns chave de idempotência inválida (400 bad request) curl location '{gateway host}/v2/flows/test?key={api key}' \\ \ header 'x idempotency key chave inválida!' \\ \ data '{}' \# resposta http/1 1 400 bad request { "code" "400", "message" "invalid idempotency key idempotency key contains invalid characters (allowed a z, a z, 0 9, , , )" } chave muito pequena ou muito grande \# chave muito pequena (< 3 caracteres) x idempotency key ab \# chave muito grande (> 128 caracteres) x idempotency key \[string com 129+ caracteres] \# resposta http/1 1 400 bad request { "code" "400", "message" "invalid idempotency key idempotency key too short (min 3 chars)" } outros erros não relacionados à idempotência \# flow não encontrado http/1 1 400 bad request { "code" "400", "message" "missing 'flow' parameter in path" } \# api key inválida http/1 1 401 unauthorized { "code" "401", "message" "unauthorized" } combinando com outros parâmetros a idempotência funciona normalmente com todos os outros recursos do gateway \# fluxo síncrono com idempotência e tags curl location '{gateway host}/v2/flows/processar pedido?sync=true\&return step=resposta\&tags=ecommerce,urgente\&key={api key}' \\ \ header 'content type application/json' \\ \ header 'x idempotency key pedido 789 retry 001' \\ \ data '{ "produtos" \[{"id" 1, "quantidade" 2}], "cliente id" "user 456" }' boas práticas gerando chaves de idempotência ✅ boas práticas // incluir contexto + timestamp + identificador único const key = `pagamento ${userid} ${timestamp} ${uuid}`; // para retry de webhook específico const key = `webhook ${originaleventid} retry ${attemptnumber}`; // baseado em dados únicos da transação const key = `pedido ${orderid} ${customeremail} ${totalamount}`; ❌ evite // muito genérico const key = "pagamento 123"; // baseado apenas em timestamp (pode duplicar) const key = date now() tostring(); // caracteres inválidos const key = "pagamento user\@123!"; tratamento de erros const response = await fetch(' /flows/meu fluxo', { method 'post', headers { 'content type' 'application/json', 'x idempotency key' gerarchaveunica(), 'x api key' apikey }, body json stringify(dados) }); const idempotencystatus = response headers get('x idempotency status'); if (idempotencystatus === 'duplicate') { console log('requisição já foi processada anteriormente'); } else if (idempotencystatus === 'processing') { console log('requisição ainda está sendo processada'); } integração com webhooks ao receber webhooks que podem ser reenviados, use uma chave baseada no id único do evento \# webhook do sistema externo curl location ' /flows/processar webhook?key={api key}' \\ \ header 'x idempotency key webhook ${sistemaexterno} ${eventoid}' \\ \ data '${payloadwebhook}' limitações atuais resultados síncronos por ora, o sistema não cacheia o resultado de execuções síncronas requisições duplicadas retornam apenas metadados (event id, status) sem o corpo da resposta original escopo por tenant chaves de idempotência são isoladas por tenant (api key) a mesma chave pode ser usada por diferentes tenants sem conflito monitoramento use os headers de resposta para monitorar o comportamento da idempotência function logidempotencymetrics(response) { const key = response headers get('x idempotency key'); const status = response headers get('x idempotency status'); console log(`idempotency key ${key}, status ${status}`); // métricas para observabilidade if (status === 'duplicate') { metrics increment('gateway idempotency duplicate'); } else if (status === 'new') { metrics increment('gateway idempotency new'); } }
