Fluxo order.created
Consistência eventual na prática
Você implementa estados transitórios de pedido e deixa a API honesta sobre o processamento assíncrono.
Nesta aula você vai
- Modelar estados de pedido em processamento assíncrono
- Expor consulta de status compatível com consistência eventual
- Implementar atualização de estado após retorno do pagamento
Consistência eventual na prática
Objetivos
- Modelar estados de pedido em processamento assíncrono
- Expor consulta de status compatível com consistência eventual
- Implementar atualização de estado após retorno do pagamento
Pré-requisitos
- Fluxo
order.createdjá publicado/consumido order-servicecom criação de pedidospayment-serviceprocessando eventos
Conceito
Consistência eventual não é bug: é escolha arquitetural. Em sistemas orientados a eventos, a criação do pedido e a confirmação de pagamento acontecem em momentos diferentes. Se a API esconde isso, o usuário recebe informação incorreta e o time perde rastreabilidade.
O correto é modelar estados transitórios explícitos (PENDING_PAYMENT, PAID, PAYMENT_FAILED) e atualizar o pedido quando o evento de pagamento chegar. Assim, o produto comunica o estado real do negócio sem prometer sincronismo inexistente.
Nesta aula, você implementa essa máquina de estados de ponta a ponta: criação de pedido, consulta de status e atualização assíncrona no order-service.
Estrutura de arquivos
services/order-service/app/repository/order_repository.py
services/order-service/app/api/orders.py
services/order-service/app/consumers/payment_result_consumer.py
services/payment-service/internal/publishers/payment_result_publisher.go
contracts/events/payment-approved.v1.json
contracts/events/payment-failed.v1.json
Passo a passo
- Definir estados no
order_repository.py
class OrderRepository:
_db = {}
def save(self, order: dict):
self._db[order["id"]] = order
return order
def get(self, order_id: str):
return self._db.get(order_id)
def update_status(self, order_id: str, status: str):
if order_id in self._db:
self._db[order_id]["status"] = status
- Retornar estado real no endpoint de consulta
@router.get("/{order_id}")
def get_order(order_id: str):
order = service.get_by_id(order_id)
if not order:
raise HTTPException(status_code=404, detail="pedido não encontrado")
return {
"id": order["id"],
"customer_id": order["customer_id"],
"total_amount": order["total_amount"],
"status": order["status"]
}
- Atualizar estado do pedido com eventos de pagamento
# payment_result_consumer.py
def handle_payment_approved(event: dict):
repo.update_status(event["orderId"], "PAID")
def handle_payment_failed(event: dict):
repo.update_status(event["orderId"], "PAYMENT_FAILED")
- Publicar resultado no
payment-service(Go)
type PaymentResultEvent struct {
EventID string `json:"eventId"`
OrderID string `json:"orderId"`
Status string `json:"status"`
Reason string `json:"reason,omitempty"`
OccurredAt string `json:"occurredAt"`
}
Como testar
- Subir stack:
docker compose -f infra/docker-compose.yml up --build -d
- Criar pedido:
ORDER=$(curl -s -X POST http://localhost:8000/orders \
-H "Content-Type: application/json" \
-d '{"customer_id":"cli-500","total_amount":120.00,"currency":"BRL"}')
echo "$ORDER"
- Consultar status logo após criação:
curl -s http://localhost:8000/orders/<ORDER_ID>
Esperado inicial: status: "PENDING_PAYMENT".
- Após processamento do payment, consultar novamente:
curl -s http://localhost:8000/orders/<ORDER_ID>
Esperado final: status: "PAID" ou status: "PAYMENT_FAILED".
Dicas de projeto
- Use nomes de status legíveis para produto e suporte.
- Defina SLA para tempo máximo em
PENDING_PAYMENT. - Mantenha transição de estado só por evento de domínio.
- Logue cada mudança de status com
correlationId.
Erros comuns
- Retornar "pedido pago" no
POST /orderssem confirmação. - Atualizar status por timer em vez de evento.
- Não tratar pedidos presos em pendência.
- Confundir estado de UI com estado de domínio.
Resumo
Você implementou consistência eventual de forma explícita no domínio e na API. O fluxo de pedidos agora comunica estado real ao usuário e prepara o terreno para notificação de pagamento.