Analytics e Múltiplos Eventos
Estatísticas em tempo quase real
Expondo API de métricas com atualização incremental e latência baixa.
Nesta aula você vai
- Expor endpoint analítico com dados agregados em quase tempo real
- Calcular taxa de conversão entre pedidos e pagamentos
- Publicar timestamp de atualização para transparência de atraso
Estatísticas em tempo quase real
Objetivos
- Criar endpoint HTTP para visão consolidada do funil.
- Calcular métricas incrementais sem consulta pesada por requisição.
- Entregar observabilidade de atualização (
lastUpdatedAt).
Pré-requisitos
- Aulas 1 e 2 concluídas na matéria.
analytics-servicejá consumindo eventos.- Express configurado no serviço Node.
Conceito
"Quase tempo real" não significa atualização instantânea. Significa atraso pequeno e controlável. Aqui, a projeção é atualizada no consumo Kafka e a API só devolve o snapshot pronto.
Estrutura de arquivos
services/analytics-service/src/
├── api/
│ └── analytics-routes.js
├── store/
│ └── metrics-store.js
└── app.js
Passo a passo
- Expanda o
metrics-store.jspara cálculos de conversão:
const state = {
totals: { orders: 0, paymentsApproved: 0, notificationsSent: 0 },
revenueCents: 0,
lastUpdatedAt: null,
};
export function getDashboardStats() {
const conversionRate =
state.totals.orders === 0
? 0
: Number((state.totals.paymentsApproved / state.totals.orders).toFixed(4));
return {
...state,
conversionRate,
averageTicketCents:
state.totals.paymentsApproved === 0
? 0
: Math.round(state.revenueCents / state.totals.paymentsApproved),
};
}
- Crie rotas HTTP em
services/analytics-service/src/api/analytics-routes.js:
import { Router } from "express";
import { getDashboardStats } from "../store/metrics-store.js";
export const analyticsRoutes = Router();
analyticsRoutes.get("/stats", (_, res) => {
const stats = getDashboardStats();
res.json({
totals: stats.totals,
revenueCents: stats.revenueCents,
conversionRate: stats.conversionRate,
averageTicketCents: stats.averageTicketCents,
lastUpdatedAt: stats.lastUpdatedAt,
});
});
- Registre as rotas em
services/analytics-service/src/app.js:
import express from "express";
import { analyticsRoutes } from "./api/analytics-routes.js";
import { startKafkaConsumer } from "./consumers/kafka-consumer.js";
const app = express();
app.use(express.json());
app.use("/analytics", analyticsRoutes);
await startKafkaConsumer();
app.listen(8085, () => console.log("analytics-service em 8085"));
Como testar
Gerar eventos e consultar estatísticas:
docker compose up -d
curl -s -X POST http://localhost:8002/orders \
-H "Content-Type: application/json" \
-d '{"customerId":"c-10","amountCents":29990}'
curl -s http://localhost:8085/analytics/stats | jq
Exemplo esperado:
{
"totals": { "orders": 1, "paymentsApproved": 1, "notificationsSent": 1 },
"revenueCents": 29990,
"conversionRate": 1,
"averageTicketCents": 29990,
"lastUpdatedAt": "2026-07-03T18:20:10.120Z"
}
Dicas de projeto
- Exponha números em centavos para evitar erro de ponto flutuante.
- Tenha métrica de lag do consumer para explicar atrasos.
- Separe endpoint de dashboard e endpoint de debug.
Erros comuns
- Recalcular tudo com query no banco a cada
GET /stats. - Não informar
lastUpdatedAt. - Considerar
conversionRatecom divisão por zero.
Resumo
Você fechou o ciclo da matéria de analytics: consumo de múltiplos eventos, projeção incremental e endpoint de estatísticas quase em tempo real.