Skip to main content

Document Generation

getAsyncApiDocument() is the AsyncAPI counterpart to SwaggerModule.createDocument. It walks a running application's NestJS metadata exactly as @nestjs/swagger walks controllers, then assembles a spec-compliant AsyncAPI 3.0 document.

import { NestFactory } from '@nestjs/core';
import { getAsyncApiDocument } from '@nest-native/asyncapi';
import { AppModule } from './app.module';

const app = await NestFactory.create(AppModule);

const document = getAsyncApiDocument(app, {
title: 'Orders Service',
version: '1.0.0',
description: 'Event-driven order lifecycle, documented with AsyncAPI 3.0.',
});

The Metadata Walk​

The generator resolves the application's ModulesContainer and uses a MetadataScanner to visit every provider and controller class. For each class it reads the AsyncAPI metadata left by the decorators:

  • @AsyncApiChannel makes a class a channel handler. Classes without it contribute nothing.
  • Each @AsyncApiPub / @AsyncApiSub method becomes one operation referencing the class's channel.
  • @AsyncApiMessage / @AsyncApiHeaders register schemas under components.schemas and a message under components.messages, referenced via $ref.
  • @AsyncApiServer declarations merge into the document's servers map.
  • Binding decorators attach protocol bindings verbatim.

No extra module import is required in the consuming application — the walk reads the running app you already created.

Document Config​

The second argument seeds the document's info object. Every field is optional.

FieldPurposeDefault
titleApplication titleAsyncAPI
versionDocument/API version (distinct from the spec version, always 3.0.0)1.0.0
descriptionShort application description—
termsOfServiceURL to the Terms of Service—
contactContact { name?, url?, email? }—
licenseLicense { name, url? }—

Channels, operations, messages, and servers are discovered from metadata and are never configured here. This is the AsyncAPI counterpart to @nestjs/swagger's DocumentBuilder for the parts that cannot be derived from code.

Versioning​

Three versions appear in the output and are intentionally distinct:

  • The spec version is always 3.0.0 (the asyncapi field).
  • The document version is your API version (info.version, default 1.0.0), set through the config.
  • A server version is the broker protocol version (@AsyncApiServer's protocolVersion), independent of both.

Empty But Valid​

An application with no AsyncAPI decorators still produces a valid (empty) AsyncAPI 3.0 document: info plus empty channels, operations, and components. This lets you wire generation in first and decorate handlers incrementally.

Validating The Output​

Every generated document is treated as valid only when it passes the official @asyncapi/parser. Add a check in a smoke test:

import { Parser } from '@asyncapi/parser';
import { getAsyncApiDocument } from '@nest-native/asyncapi';

const document = getAsyncApiDocument(app, { title: 'Orders', version: '1.0.0' });
const { diagnostics } = await new Parser().parse(document as never);

const errors = diagnostics.filter((d) => d.severity === 0);
if (errors.length > 0) {
throw new Error(`Invalid AsyncAPI document: ${JSON.stringify(errors)}`);
}

Treat parser errors as build failures. Every sample in this repository validates its generated document this way.

Serialization​

The document is plain JSON data. Serialize it with the exported helpers:

import { toJson, toYaml } from '@nest-native/asyncapi';

const json = toJson(document); // indented JSON
const yaml = toYaml(document); // block-style YAML 1.2

YAML is the canonical AsyncAPI interchange format, and JSON is offered alongside. The YAML emitter is dependency-free, keeping the published package at "dependencies": {}. To serve both over HTTP, see Docs Route.