Pular para o conteúdo

apps/patterns/async-request-reply

002 · Padrões Fundamentais · ≈ 5 min de estudo

Async Request-Reply

Desacopla o envio da resposta: a API responde 202 Accepted com um requestId e um Location na hora, um worker processa em background e o cliente consulta o resultado depois, por polling. Use quando a operação demora mais do que o cliente pode esperar numa requisição HTTP.

passos
6
arquivos
10
testes
2
tecnologias
5
Infraestrutura realTypeScriptBunElysiaRedisDocker
Baixar cartão

Cenário

Um banco digital recebe ordens de PIX. A liquidação passa por clearing e análise de fraude e leva centenas de milissegundos, então o app não pode ficar bloqueado. Duas transferências são liquidadas, uma acima do limite por transação é recusada e um reenvio do cliente com a mesma chave recebe o mesmo requestId, sem segunda transferência.

Planta

Sequência
12/12
POST /pix + Idempotency-Key1SET NX pix:idem:{key}2SET pix:job:{id} pending EX 3003XADD pix:transfers4202 Accepted + Location /status/{id}5XREADGROUP pix-settlement6liquida o PIX (clearing e fraude)7SET pix:job:{id} completed ou failed8XACK9GET /status/{id} (backoff exponencial)10GET pix:job:{id}11completed + endToEndId12ClienteAPI PIX (Elysia)RedisWorker de liquidação
12

12 passos — reproduza para seguir o fluxo

Como funciona

6 passos

Aceita agora, entrega o resultado depois.

Esconde cada passo: lembre antes de tocar para revelar.

  1. 01

    Submissão idempotenteSET NX da Idempotency-Key — o reenvio devolve o requestId original e não enfileira de novo

  2. 02

    202 + LocationO job nasce pending no Redis com TTL de 5 minutos e a resposta aponta para /status/<requestId>

  3. 03

    FilaO PIX entra no stream pix:transfers; a entrada fica pendente no consumer group até o worker confirmar

  4. 04

    WorkerProcesso separado, com concorrência limitada, que liquida, grava o resultado e só então faz XACK; reentrega de job já liquidado recebe ack sem novo efeito

  5. 05

    PollingO cliente consulta GET /status/:requestId com backoff exponencial e teto; 404 para id desconhecido ou expirado

  6. 06

    DesligamentoNo SIGTERM o worker para de ler, drena o que está em curso com prazo e fecha as conexões

apps/patterns/async-request-reply

10 arquivos

src/

  • api_pix.tsAPI Elysia: POST /pix (202 + Location) e GET /status/:requestId
  • worker_pix.tsWorker: leitura do stream, probes, métricas e drenagem no SIGTERM
  • settlement_pix.tsLiquidação do PIX, idempotente por requestId
  • queue_pix.tsStream e consumer group do Redis
  • store_pix.tsJob store e chave de idempotência com TTL
  • redis_pix.tsConexão com o Redis com prazo no boot
  • config_pix.tsLê e valida o ambiente no boot
  • api_pix.test.tstesteIntegração contra Redis real: 202, idempotência, reentrega, TTL
  • settlement_pix.test.tstesteLimite por transação: abaixo, em cima e acima

./

  • docker.shinfraSobe o Redis

Executar · com Docker

  1. ./docker.sh up# sobe Redis
  2. bun install# dependências
  3. bun run demo# roda o cenário

O demo.ts sobe a API e o worker como processos separados (Bun.spawn) e atua como cliente HTTP. Testes: bun run test.

Requisitos
BunDocker
Sobe junto
Redis

Por que se relacionam

Teste rápido

Qual destes combina com Async Request-Reply?

Próximo projeto · Padrões FundamentaisBulkhead Isolation
Esc

↑ ↓ navegarEnter abrir191 resultados