Analytics e Múltiplos Eventos

Estatísticas em tempo quase real

Expondo API de métricas com atualização incremental e latência baixa.

Avançado 30 min 25 pontos Leitura 0%

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-service já 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

  1. Expanda o metrics-store.js para 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),
  };
}
  1. 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,
  });
});
  1. 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 conversionRate com 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.