Fluxo order.created
Order publica, Payment consome
Você conecta order-service e payment-service via Kafka, sem dependência síncrona.
Nesta aula você vai
- Publicar `order.created.v1` após criação de pedido
- Consumir evento no serviço de pagamento em Go
- Implementar tratamento básico de erro e logs de rastreio
Order publica, Payment consome
Objetivos
- Publicar
order.created.v1após criação de pedido - Consumir evento no serviço de pagamento em Go
- Implementar tratamento básico de erro e logs de rastreio
Pré-requisitos
- Contrato
order.created.v1modelado order-serviceepayment-serviceativos- Kafka configurado no Compose
Conceito
O fluxo de pedido para pagamento é crítico e não pode depender de chamada HTTP em cadeia. Se o payment-service estiver indisponível por alguns segundos, o pedido ainda deve ser criado com sucesso, e o processamento deve ocorrer depois.
Kafka permite exatamente esse desacoplamento temporal: o order-service publica o evento e segue. O consumidor no payment-service processa quando estiver pronto, mantendo confiabilidade e capacidade de reprocessamento.
Nesta aula você implementa producer em Python e consumer em Go, incluindo parsing de payload, logs de offset e criação inicial de status de pagamento.
Estrutura de arquivos
services/order-service/app/events/order_publisher.py
services/order-service/app/service/order_service.py
services/payment-service/internal/consumers/order_created_consumer.go
services/payment-service/internal/service/payment_service.go
contracts/events/order-created.v1.json
Passo a passo
- Implementar publisher no
order-service(Python)
# app/events/order_publisher.py
import json
from kafka import KafkaProducer
class OrderPublisher:
def __init__(self):
self.producer = KafkaProducer(
bootstrap_servers="kafka:9092",
value_serializer=lambda v: json.dumps(v).encode("utf-8"),
)
def publish_order_created(self, event: dict):
self.producer.send("order.created.v1", key=event["orderId"].encode("utf-8"), value=event)
self.producer.flush()
- Publicar evento no fluxo de criação de pedido
# app/service/order_service.py
event = build_order_created_event(order, correlation_id)
self.publisher.publish_order_created(event)
- Implementar consumidor em Go
// internal/consumers/order_created_consumer.go
package consumers
import (
"context"
"encoding/json"
"log"
"github.com/segmentio/kafka-go"
)
type OrderCreatedEvent struct {
EventID string `json:"eventId"`
OrderID string `json:"orderId"`
CustomerID string `json:"customerId"`
Amount float64 `json:"amount"`
Currency string `json:"currency"`
}
func StartOrderCreatedConsumer() {
reader := kafka.NewReader(kafka.ReaderConfig{
Brokers: []string{"kafka:9092"},
Topic: "order.created.v1",
GroupID: "payment-service-order-group",
})
for {
msg, err := reader.ReadMessage(context.Background())
if err != nil {
log.Printf("erro no consumo: %v", err)
continue
}
var event OrderCreatedEvent
if err := json.Unmarshal(msg.Value, &event); err != nil {
log.Printf("payload inválido offset=%d", msg.Offset)
continue
}
log.Printf("order.created recebido orderId=%s partition=%d offset=%d", event.OrderID, msg.Partition, msg.Offset)
}
}
- Iniciar consumer no
main.godo payment-service
go consumers.StartOrderCreatedConsumer()
router.Run(":8080")
Como testar
- Subir serviços:
docker compose -f infra/docker-compose.yml up --build -d kafka order-service payment-service
- Criar pedido:
curl -s -X POST http://localhost:8000/orders \
-H "Content-Type: application/json" \
-H "X-Correlation-Id: corr-pay-100" \
-d '{"customer_id":"cli-100","total_amount":349.90,"currency":"BRL"}'
- Verificar consumo:
docker compose -f infra/docker-compose.yml logs -f payment-service
Saída esperada:
order.created recebido orderId=<id> partition=<n> offset=<n>
- Testar múltiplos pedidos:
for i in 1 2 3; do
curl -s -X POST http://localhost:8000/orders \
-H "Content-Type: application/json" \
-d "{\"customer_id\":\"cli-$i\",\"total_amount\":99.$i,\"currency\":\"BRL\"}" >/dev/null
done
Dicas de projeto
- Producer deve publicar só depois de persistir pedido.
- Consumer deve separar parsing e regra de negócio.
- Logue
partition,offseteorderId. - Prepare idempotência para lidar com reentrega.
Erros comuns
- Fazer chamada REST de volta para confirmar recebimento.
- Consumir sem validar payload obrigatório.
- Esquecer de tratar erro de deserialização.
- Assumir ordem global em múltiplas partições.
Resumo
Order e Payment agora estão integrados por eventos, com publicação e consumo reais no Kafka. O fluxo ficou desacoplado temporalmente e pronto para tratar consistência eventual de forma explícita.