Criar pedido
Fluxo de criação de um pedido: do frontend até o microsserviço de pedidos, com publicação de eventos e coordenação com estoque e pagamentos.
Por que a criação de pedido é um fluxo complexo
Criar um pedido não é simplesmente salvar um registro em um banco de dados. É um fluxo que envolve múltiplos serviços, validações de negócio, reserva de estoque, início de pagamento e notificações. É o exemplo perfeito de como a comunicação síncrona e assíncrona convivem em um mesmo caso de uso.
O fluxo completo
sequenceDiagram
participant FE as Frontend
participant GW as API Gateway
participant BFF as BFF
participant ORD as ms-orders
participant DB as Orders DB
participant EB as Event Bus
participant INV as ms-inventory
participant PAY as ms-payments
participant NOT as ms-notifications
FE->>GW: POST /orders
GW->>GW: Auth, rate limiting
GW->>BFF: Forward
BFF->>ORD: Crear orden
ORD->>ORD: Validar datos de la orden
ORD->>DB: Guardar orden (estado: pending)
DB-->>ORD: OK
ORD->>EB: Publicar OrderPlaced
ORD-->>BFF: Orden creada (id, estado)
BFF-->>GW: Respuesta para UI
GW-->>FE: 201 Created + orden
Note over EB: Procesamiento asíncrono
EB->>INV: OrderPlaced
INV->>INV: Reservar stock
INV->>EB: InventoryReserved
EB->>PAY: OrderPlaced
PAY->>PAY: Iniciar proceso de pago
EB->>NOT: OrderPlaced
NOT->>NOT: Enviar confirmación al usuario
Fase síncrona: criar o pedido
A primeira parte do fluxo é síncrona. O usuário aguarda uma confirmação de que seu pedido foi recebido.
Frontend
- O usuário revisa seu carrinho e confirma a compra
- O frontend envia os dados do pedido: itens, quantidades, endereço de entrega, método de pagamento
- Exibe um spinner enquanto aguarda a confirmação
- Recebe a confirmação com o ID do pedido e exibe uma mensagem de sucesso
BFF
- Recebe os dados do frontend
- Pode enriquecer a requisição (resolver IDs de produtos, validar formato)
- Invoca o microsserviço de pedidos
- Transforma a resposta para o frontend
Microsserviço de pedidos (ms-orders)
Este é o serviço que orquestra a criação:
- Valida os dados do pedido (itens existem, quantidades válidas, endereço completo)
- Calcula o total
- Salva o pedido em seu banco de dados com estado
pending - Publica o evento
OrderPlacedno Event Bus - Devolve o pedido criado ao BFF
Ponto-chave: o pedido é salvo e o evento é publicado na mesma operação (idealmente usando o Outbox Pattern para garantir consistência).
Fase assíncrona: coordenação entre serviços
Uma vez publicado o evento OrderPlaced, vários serviços reagem de forma independente.
Estoque (ms-inventory)
- Recebe o evento
OrderPlaced - Verifica se há estoque suficiente para cada item
- Reserva o estoque (marca como comprometido)
- Publica
InventoryReservedouInventoryInsufficient
Pagamentos (ms-payments)
- Recebe o evento
OrderPlaced - Inicia o processo de cobrança com o provedor de pagamentos
- Publica
PaymentCompletedouPaymentFailed
Notificações (ms-notifications)
- Recebe o evento
OrderPlaced - Envia um email de confirmação ao usuário
- Pode enviar uma notificação push se o app suportar
Coordenação e estados do pedido
O pedido passa por vários estados conforme os eventos que recebe:
stateDiagram-v2
[*] --> Pending: OrderPlaced
Pending --> Confirmed: InventoryReserved + PaymentCompleted
Pending --> Cancelled: InventoryInsufficient
Pending --> Cancelled: PaymentFailed
Confirmed --> Shipped: ShipmentCreated
Shipped --> Delivered: ShipmentDelivered
Cancelled --> [*]
Delivered --> [*]
O microsserviço de pedidos escuta os eventos de estoque e pagamentos para atualizar o estado:
- Se ambos forem bem-sucedidos →
confirmed - Se o estoque falhar →
cancelled(e o pagamento é revertido se já foi cobrado) - Se o pagamento falhar →
cancelled(e o estoque reservado é liberado)
O problema da consistência
Neste fluxo, não há uma transação distribuída que garanta que tudo aconteça de forma atômica. Em vez disso, usa-se consistência eventual:
- O pedido é criado no estado
pending - Os serviços processam suas partes de forma independente
- Os eventos de resultado atualizam o estado do pedido
- Se algo falhar, executam-se compensações (liberar estoque, reverter pagamento)
Este é o padrão Saga em ação: uma sequência de transações locais coordenadas por eventos.
Compensações
Quando algo falha depois que outros serviços já atuaram, são necessárias compensações:
| Falha | Compensação |
|---|---|
| Pagamento falha depois de reservar estoque | Publicar PaymentFailed → estoque libera o produto |
| Estoque insuficiente depois de iniciar o pagamento | Publicar InventoryInsufficient → pagamentos cancela a cobrança |
| Timeout sem resposta do estoque | Pedido passa a cancelled após um tempo limite |
Idempotência
Cada consumidor deve ser idempotente. Se o evento OrderPlaced for entregue duas vezes:
- O estoque não deve reservar o produto duas vezes
- Os pagamentos não devem cobrar duas vezes
- As notificações não devem enviar dois emails
A forma mais comum de conseguir isso é salvar o ID do evento processado e verificar antes de atuar.
O que o usuário vê
Da perspectiva do usuário:
- Clica em “Confirmar compra”
- Vê um spinner por 1–2 segundos
- Vê “Pedido #12345 recebido” com estado “Processando”
- Recebe um email de confirmação
- Pode consultar o estado do pedido, que é atualizado conforme os serviços processam
O usuário não precisa saber que por trás há 4 serviços se coordenando. Ele só vê um fluxo limpo.
Resumo
A criação de um pedido combina comunicação síncrona (para dar uma resposta rápida ao usuário) com comunicação assíncrona (para coordenar estoque, pagamentos e notificações). A consistência é alcançada por meio de eventos e compensações, não por meio de transações distribuídas. Cada serviço é responsável por sua parte e reage aos eventos dos demais.