Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

CloudEvents no Node.js

Atualizado em: 15 de setembro de 2026

Rack de servidores processando fluxos de dados no Node.js

O CloudEvents no Node.js padroniza a forma como aplicações descrevem eventos. Em arquiteturas orientadas a eventos, cada serviço pode publicar mensagens com campos, nomes e estruturas diferentes. Isso aumenta o acoplamento, exige adaptadores para cada origem e dificulta roteamento, observabilidade e integração entre plataformas.

CloudEvents resolve esse problema com um envelope comum. A especificação define atributos como id, source, type, specversion, subject, time e datacontenttype. O dado de negócio permanece em data. Assim, um consumidor consegue identificar, filtrar e rastrear eventos sem conhecer todos os detalhes internos do produtor.

Neste guia, você aprenderá a criar CloudEvents em Node.js, validar atributos, transmitir por HTTP e mensageria, evitar duplicidade, versionar contratos e integrar com Kafka, RabbitMQ, OpenTelemetry e Schema Registry.

O que é CloudEvents?

A documentação oficial de CloudEvents define o projeto como uma especificação para descrever dados de eventos de maneira comum. O padrão é mantido pela CNCF e possui SDKs para várias linguagens, incluindo JavaScript.

A especificação principal está no repositório oficial do CloudEvents. Ela não determina qual broker usar nem como garantir entrega. Seu objetivo é padronizar o envelope e os bindings de transporte.

Estrutura de um evento

{
  "specversion": "1.0",
  "id": "evt-8c129",
  "source": "/orders-service",
  "type": "com.codigofacil.order.created.v1",
  "subject": "orders/order-42",
  "time": "2026-09-15T12:00:00Z",
  "datacontenttype": "application/json",
  "data": {
    "orderId": "order-42",
    "customerId": "customer-7",
    "totalCents": 15990
  }
}

Os atributos obrigatórios são:

  • specversion: versão da especificação;
  • id: identificador único dentro do escopo do produtor;
  • source: contexto que originou o evento;
  • type: tipo semântico do evento.

Os demais atributos são opcionais, mas subject, time e datacontenttype são muito úteis.

Instalando o SDK JavaScript

npm install cloudevents

Depois crie um evento:

import { CloudEvent } from 'cloudevents';

const event = new CloudEvent({
  source: '/orders-service',
  type: 'com.codigofacil.order.created.v1',
  subject: 'orders/order-42',
  id: crypto.randomUUID(),
  time: new Date().toISOString(),
  datacontenttype: 'application/json',
  data: {
    orderId: 'order-42',
    customerId: 'customer-7',
    totalCents: 15990
  }
});

O construtor ajuda a validar o envelope, mas não substitui a validação do conteúdo de data. Para contratos mais fortes, use JSON Schema, Avro ou Protobuf.

Escolhendo o campo type

O atributo type precisa ser estável e descrever o fato ocorrido. Prefira algo como:

com.codigofacil.order.created.v1

Evite tipos genéricos como event, update ou message. Consumidores precisam entender o significado sem analisar o payload.

O sufixo de versão pode ser útil quando existe breaking change no contrato. Uma mudança compatível pode manter o mesmo tipo, enquanto uma alteração incompatível cria v2.

Source não é URL de callback

source identifica o contexto produtor. Pode ser uma URI absoluta ou relativa:

/orders-service
https://api.codigofacil.com.br/orders
urn:codigofacil:orders

Não use um valor que muda a cada deploy ou instância. O objetivo é identificar a origem lógica, não o pod específico.

Subject

subject identifica o recurso afetado dentro da origem:

orders/order-42

Isso facilita filtros sem abrir o payload. Entretanto, não coloque dados pessoais ou segredos. O atributo pode aparecer em logs, métricas e rotas.

Modo estruturado por HTTP

No modo estruturado, o envelope inteiro vai no corpo:

import { HTTP } from 'cloudevents';

const message = HTTP.structured(event);

await fetch('https://consumer.example.com/events', {
  method: 'POST',
  headers: message.headers,
  body: JSON.stringify(message.body)
});

O content type normalmente é application/cloudevents+json. Esse modo é simples para webhooks e APIs.

Modo binário por HTTP

No modo binário, atributos CloudEvents vão em headers e data vai no corpo:

const message = HTTP.binary(event);

await fetch('https://consumer.example.com/events', {
  method: 'POST',
  headers: message.headers,
  body: JSON.stringify(message.body)
});

Headers usam o prefixo ce-, como ce-id, ce-source e ce-type.

Recebendo CloudEvents

import { HTTP } from 'cloudevents';

app.post('/events', express.json({ type: '*/*' }), async (req, res) => {
  const event = HTTP.toEvent({
    headers: req.headers,
    body: req.body
  });

  await handler(event);
  res.status(204).end();
});

Valide tamanho do corpo, content type e autenticação antes de processar. O envelope padronizado não torna a mensagem confiável por si só.

Idempotência

Entregas podem ser repetidas. Use a combinação de source e id como chave de deduplicação:

const key = `${event.source}:${event.id}`;

if (await processedEvents.exists(key)) {
  return;
}

await processEvent(event);
await processedEvents.save(key);

O armazenamento deve respeitar o mesmo limite transacional da operação. Consulte Idempotência em APIs Node.js.

CloudEvents com Kafka

Em Kafka, o evento pode ser serializado como JSON estruturado:

await producer.send({
  topic: 'orders.events',
  messages: [
    {
      key: event.subject,
      value: JSON.stringify(event)
    }
  ]
});

Outra opção é mapear atributos para headers e manter apenas data no valor. Padronize uma estratégia para todos os produtores.

Veja Kafka com Node.js e Schema Registry no Node.js.

CloudEvents com RabbitMQ

RabbitMQ pode transportar JSON estruturado e usar type ou subject para roteamento:

channel.publish(
  'events',
  'order.created',
  Buffer.from(JSON.stringify(event)),
  {
    contentType: 'application/cloudevents+json',
    messageId: event.id,
    timestamp: Date.parse(event.time) / 1000
  }
);

Consulte RabbitMQ com Node.js.

Schema do campo data

O atributo dataschema pode apontar para o schema:

dataschema: 'https://schemas.example.com/order-created/v1.json'

O consumidor ainda precisa decidir como recuperar, armazenar e validar o schema. Em sistemas Kafka, um registry oferece IDs, versionamento e políticas de compatibilidade.

Extensões

CloudEvents permite atributos adicionais:

const event = new CloudEvent({
  source: '/orders-service',
  type: 'com.codigofacil.order.created.v1',
  id: crypto.randomUUID(),
  tenantid: 'tenant-a',
  traceparent: '00-...-...-01',
  data: payload
});

Use extensões de baixa cardinalidade e com semântica documentada. Não crie dezenas de campos que pertencem ao payload.

Tracing

Propague contexto W3C Trace Context em bindings suportados. O evento pode carregar traceparent e tracestate, permitindo ligar produtor, broker e consumidor.

Consulte OpenTelemetry no Node.js.

Outbox Pattern

CloudEvents padroniza o formato, mas não garante que a alteração no banco e a publicação ocorram juntas. Use Outbox Pattern:

  1. grave a alteração de negócio;
  2. grave o CloudEvent na tabela outbox na mesma transação;
  3. um worker publica;
  4. marque como enviado;
  5. consumidores deduplicam.

Veja Outbox Pattern no Node.js.

Versionamento

Evite alterar silenciosamente o significado de um campo. Mudanças compatíveis incluem adicionar campo opcional ou ampliar uma enumeração quando consumidores toleram valores desconhecidos. Mudanças incompatíveis incluem remover campo obrigatório, alterar tipo ou reutilizar um nome com outra semântica.

Mantenha testes de contrato com fixtures de versões anteriores.

Segurança

  • Autentique produtores.
  • Use TLS.
  • Assine webhooks quando necessário.
  • Valide tamanho e schema.
  • Não confie apenas em source.
  • Não inclua segredos em atributos.
  • Defina allowlist de tipos aceitos.
  • Registre rejeições sem expor payload sensível.

Erros comuns

  • Type genérico: consumidores não conseguem filtrar.
  • ID reutilizado: deduplicação descarta evento válido.
  • Source por instância: identificação fica instável.
  • Payload sem schema: contrato continua informal.
  • Sem idempotência: entregas repetidas duplicam efeitos.
  • Confundir padrão com broker: CloudEvents não garante entrega.
  • Breaking change silenciosa: consumidores falham.
  • Dados pessoais em subject: exposição em logs.

Conclusão

O CloudEvents no Node.js cria uma linguagem comum para eventos. Atributos padronizados tornam mensagens mais fáceis de rotear, observar, validar e transportar entre HTTP, Kafka, RabbitMQ e plataformas cloud.

Use tipos estáveis, IDs únicos, source consistente e payload com schema. Combine o padrão com idempotência, Outbox Pattern, autenticação e tracing. Assim, CloudEvents deixa de ser apenas um envelope bonito e se torna parte de uma arquitetura orientada a eventos realmente interoperável.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita