O AsyncAPI no Node.js oferece uma forma padronizada de documentar APIs orientadas a eventos. Em sistemas com Kafka, RabbitMQ, NATS, WebSockets ou MQTT, produtores e consumidores precisam concordar sobre canais, mensagens, payloads, headers, autenticação e responsabilidades. Sem uma especificação central, esses contratos ficam espalhados em código, wikis e exemplos desatualizados.
AsyncAPI cumpre para eventos um papel semelhante ao que OpenAPI exerce em APIs HTTP. Um documento YAML ou JSON descreve servidores, operações, canais, mensagens e schemas. A partir dele, ferramentas podem gerar documentação, validar contratos, produzir código, criar mocks e apoiar governança.
Neste guia, você aprenderá a criar uma especificação AsyncAPI para Node.js, modelar publish e subscribe, reutilizar schemas, documentar Kafka e WebSockets, gerar documentação, validar no CI e evitar contratos que parecem corretos, mas não representam o comportamento real.
O que é AsyncAPI?
A documentação oficial do AsyncAPI apresenta a iniciativa como um projeto open source voltado a tornar arquiteturas orientadas a eventos tão fáceis de usar quanto APIs REST. O ecossistema inclui especificação, geradores, parsers, templates e ferramentas de documentação.
A especificação completa está no repositório oficial AsyncAPI Spec. Antes de adotar uma versão, confirme quais ferramentas do seu pipeline já oferecem suporte a ela.
Primeiro documento
asyncapi: 3.0.0
info:
title: Orders Events API
version: 1.0.0
description: Eventos do domínio de pedidos
servers:
production:
host: kafka.example.com:9092
protocol: kafka
channels:
ordersCreated:
address: orders.created.v1
messages:
orderCreated:
$ref: '#/components/messages/OrderCreated'
operations:
publishOrderCreated:
action: send
channel:
$ref: '#/channels/ordersCreated'
messages:
- $ref: '#/channels/ordersCreated/messages/orderCreated'O documento define que a aplicação envia uma mensagem para o tópico orders.created.v1.
Info
A seção info identifica a API:
info:
title: Orders Events API
version: 1.0.0
description: Contratos de eventos do serviço de pedidos
contact:
name: Time de Pedidos
email: orders@example.com
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0A versão do documento representa o contrato AsyncAPI, não necessariamente a versão do serviço ou de cada mensagem.
Servers
Servidores descrevem ambientes e protocolos:
servers:
development:
host: localhost:9092
protocol: kafka
description: Kafka local
production:
host: kafka.example.com:9093
protocol: kafka-secure
security:
- saslScram: []Evite colocar senhas, tokens ou hosts internos sensíveis em especificações públicas.
Channels
Channels representam tópicos, filas, exchanges ou destinos:
channels:
orderEvents:
address: orders.events.v1
title: Eventos de pedidos
description: Eventos imutáveis do ciclo de vida do pedido
messages:
orderCreated:
$ref: '#/components/messages/OrderCreated'
orderCancelled:
$ref: '#/components/messages/OrderCancelled'O significado de address depende do protocolo. Em Kafka é normalmente o tópico; em MQTT pode conter parâmetros de tópico; em WebSockets pode representar um caminho lógico.
Operations
Na especificação 3.x, operações usam action: send ou action: receive:
operations:
sendOrderCreated:
action: send
channel:
$ref: '#/channels/orderEvents'
messages:
- $ref: '#/channels/orderEvents/messages/orderCreated'
receiveOrderCreated:
action: receive
channel:
$ref: '#/channels/orderEvents'
messages:
- $ref: '#/channels/orderEvents/messages/orderCreated'Defina a perspectiva da aplicação descrita. send significa que ela envia; receive significa que ela recebe.
Mensagens
components:
messages:
OrderCreated:
name: order.created
title: Pedido criado
summary: Emitido após confirmação do pedido
contentType: application/json
headers:
$ref: '#/components/schemas/EventHeaders'
payload:
$ref: '#/components/schemas/OrderCreatedPayload'
examples:
- name: Pedido simples
payload:
orderId: order-42
customerId: customer-7
totalCents: 15990
occurredAt: '2026-09-15T12:00:00Z'Exemplos ajudam consumidores, mas precisam passar pela mesma validação dos schemas.
Schemas reutilizáveis
components:
schemas:
EventHeaders:
type: object
required: [messageId, correlationId]
properties:
messageId:
type: string
format: uuid
correlationId:
type: string
OrderCreatedPayload:
type: object
additionalProperties: false
required:
- orderId
- customerId
- totalCents
- occurredAt
properties:
orderId:
type: string
customerId:
type: string
totalCents:
type: integer
minimum: 0
occurredAt:
type: string
format: date-timeEm JSON Schema, additionalProperties: false torna o contrato mais rígido. Use conscientemente: adicionar um campo pode quebrar consumidores que validam estritamente.
CloudEvents
Você pode modelar um envelope CloudEvents:
CloudEvent:
type: object
required: [specversion, id, source, type, data]
properties:
specversion:
const: '1.0'
id:
type: string
source:
type: string
format: uri-reference
type:
type: string
subject:
type: string
time:
type: string
format: date-time
data:
$ref: '#/components/schemas/OrderCreatedPayload'Veja CloudEvents no Node.js.
Kafka bindings
Bindings descrevem detalhes específicos do protocolo:
channels:
orderEvents:
address: orders.events.v1
bindings:
kafka:
topicConfiguration:
cleanup.policy:
- delete
retention.ms: 604800000Use bindings apenas para propriedades realmente relevantes ao contrato. Configurações operacionais podem pertencer a infraestrutura como código.
Consulte Kafka com Node.js.
RabbitMQ bindings
channels:
orderEvents:
address: orders.events
bindings:
amqp:
is: routingKey
exchange:
name: orders
type: topic
durable: true
autoDelete: falseVeja RabbitMQ com Node.js.
WebSockets
AsyncAPI também documenta WebSockets:
servers:
realtime:
host: api.example.com
pathname: /ws
protocol: wss
channels:
notifications:
address: notifications
messages:
notification:
$ref: '#/components/messages/Notification'Documente autenticação, formato de frames, heartbeat, reconexão e regras de assinatura. O schema por si só não explica lifecycle da conexão.
Segurança
components:
securitySchemes:
saslScram:
type: scramSha256
bearerAuth:
type: httpApiKey
in: header
name: AuthorizationUma especificação pode declarar o mecanismo, mas não deve carregar credenciais.
Parser no Node.js
npm install @asyncapi/parserimport { Parser } from '@asyncapi/parser';
import { readFile } from 'node:fs/promises';
const source = await readFile('asyncapi.yaml', 'utf8');
const parser = new Parser();
const { document, diagnostics } = await parser.parse(source);
if (diagnostics.some(item => item.severity === 0)) {
console.error(diagnostics);
process.exitCode = 1;
}
console.log(document?.info().title());A API pode mudar entre versões. Fixe a dependência e use a documentação correspondente.
Validação no CI
Adicione um script:
{
"scripts": {
"asyncapi:validate": "asyncapi validate asyncapi.yaml"
}
}No pipeline:
- run: npm ci
- run: npm run asyncapi:validate
- run: npm test
- run: npm run buildConsulte CI para Node.js com GitHub Actions.
Gerando documentação
O AsyncAPI Generator pode produzir HTML a partir da especificação:
npx @asyncapi/cli generate fromTemplate \
asyncapi.yaml \
@asyncapi/html-template \
-o docs/asyncapiConfirme o comando e template suportados pela versão instalada. Gere a documentação no CI e publique como artifact ou site interno.
Geração de código
Templates podem gerar modelos, produtores, consumidores e configurações. Código gerado deve ser revisado e testado. Evite editar arquivos gerados manualmente; alterações serão perdidas na próxima geração.
Contrato primeiro
Em um fluxo contract-first:
- proponha a mudança no AsyncAPI;
- revise com produtores e consumidores;
- valide compatibilidade;
- gere tipos ou fixtures;
- implemente produtor;
- implemente consumidor;
- publique gradualmente.
Código primeiro
Em code-first, decorators ou schemas do código geram o documento. Esse modelo reduz duplicação, mas pode esconder decisões de contrato dentro do framework. Mesmo assim, revise a especificação resultante como artefato público.
Compatibilidade
AsyncAPI documenta o contrato, mas não garante compatibilidade automaticamente. Para eventos com Avro ou Protobuf, use um registry. Para JSON Schema, mantenha testes que comparem versões e fixtures antigas.
Veja Schema Registry no Node.js.
Versionamento de mensagens
Existem estratégias diferentes:
- versão no nome do tópico;
- versão no tipo da mensagem;
- versão no envelope;
- compatibilidade no schema sem novo tópico.
Não misture estratégias sem uma política. Documente quando criar v2 e quanto tempo manter consumidores antigos.
Tags e organização
tags:
- name: orders
description: Domínio de pedidos
- name: billing
description: FaturamentoTags ajudam portais e filtros. Não use centenas de tags de baixa qualidade.
Correlation ID
Documente como correlacionar mensagens:
correlationId:
description: ID de correlação do fluxo
location: '$message.header#/correlationId'A sintaxe depende da versão da especificação. Valide no parser.
Operações assíncronas não são RPC
Evite modelar cada evento como uma chamada síncrona disfarçada. Eventos representam fatos. Comandos representam intenções. Respostas podem chegar em outro canal, mas isso exige timeout, correlação e tratamento de entrega duplicada.
Ownership
Cada canal e mensagem precisa de owner. Inclua contato e regras de suporte. Um contrato sem responsável tende a ficar desatualizado.
Portal de eventos
Organizações podem publicar documentos AsyncAPI em um catálogo pesquisável. Isso ajuda equipes a descobrir eventos antes de criar tópicos duplicados.
Testes de contrato
Produtores devem validar mensagens antes de publicar:
const parsed = OrderCreatedSchema.parse(event.data);
await producer.send({ value: JSON.stringify(parsed) });Consumidores também validam, porque uma mensagem pode vir de versão antiga ou produtor incorreto.
Observabilidade
Use nomes definidos na especificação como atributos de logs e traces:
- messaging.system;
- messaging.destination.name;
- messaging.operation.name;
- event.type;
- message.id;
- correlation.id.
Erros comuns
- Perspectiva invertida: send e receive ficam errados.
- Exemplo inválido: documentação contradiz schema.
- Canal sem owner: manutenção fica indefinida.
- Documento sem CI: erros chegam ao portal.
- Contrato desatualizado: código diverge.
- Detalhes operacionais demais: especificação fica instável.
- Versionamento confuso: consumidores não sabem migrar.
- Gerar código e não testar: output quebra em runtime.
Estrutura recomendada
project/
├── asyncapi.yaml
├── schemas/
│ ├── order-created.json
│ └── order-cancelled.json
├── examples/
│ ├── order-created.json
│ └── order-cancelled.json
├── src/
└── scripts/
└── validate-asyncapi.jsConclusão
O AsyncAPI no Node.js transforma canais e mensagens em contratos explícitos. Servidores, operações, schemas e bindings deixam de existir apenas no código e passam a alimentar documentação, validação e geração de artefatos.
Use a especificação como parte do processo de desenvolvimento: valide no CI, teste exemplos, defina ownership e revise compatibilidade antes de publicar. Com AsyncAPI, arquiteturas orientadas a eventos ganham a mesma disciplina que equipes já aplicam a APIs HTTP com OpenAPI.



