Channels
export default {
...,
generators: [
{
preset: 'channels',
outputPath: './src/__gen__/',
language: 'typescript',
protocols: ['nats']
}
]
};
channels preset with asyncapi input generates support functions for each operation based on the selected protocol.
This generator uses payloads, headers and parameters generators, in case you dont have any defined, it will automatically include them with default values.
This is supported through the following inputs: asyncapi
It supports the following languages; typescript
It supports the following protocols; nats, kafka, mqtt, amqp, event_source, http_client, websocket
Optionsβ
These are the available options for the channels generator;
| Option | Default | Type | DescriptionΒ |
|---|---|---|---|
| asyncapiReverseOperations | false | Boolean | Used in conjunction with AsyncAPI input, and reverses the operation actions i.e. send becomes receive and receive becomes send. Often used in testing scenarios to act as the reverse API. |
| asyncapiGenerateForOperations | true | Boolean | Used in conjunction with AsyncAPI input, which if true generate the functions upholding how operations are defined. If false the functions are generated regardless of what operations define. I.e. send and receive does not matter. |
| functionTypeMapping | {} | Record<String, ChannelFunctionTypes[]> | Used in conjunction with AsyncAPI input, can define channel ID along side the type of functions that should be rendered. |
| kafkaTopicSeparator | '.' | String | Used with AsyncAPI to ensure the right character separate topics, example if address is my/resource/path it will be converted to my.resource.path |
| eventSourceDependency | '@microsoft/fetch-event-source' | String | Because @microsoft/fetch-event-source is out-dated in some areas we allow you to change the fork/variant that can be used instead |
| organization | 'flat' | 'flat' | 'tag' | 'path' | Controls how generated channel functions are organized in the barrel index.ts. flat re-exports each function directly under its protocol namespace (default, unchanged). tag groups them under their API tag (operation tag first, then a v3 channel tag, otherwise an untagged bucket). path nests them by URL path / channel address segments; the leaf is the HTTP method for OpenAPI and a clean action verb (publish, subscribe, jetStreamPublish, β¦) for AsyncAPI. Only the barrel shape changes β the per-protocol function code is identical across styles. See Organization |
TypeScriptβ
Regardless of protocol, these are the dependencies:
- If validation enabled, ajv: ^8.17.1
Depending on which protocol, these are the dependencies:
NATS: https://github.com/nats-io/nats.js v2Kafka: https://github.com/tulios/kafkajs v2MQTT: https://github.com/mqttjs/MQTT.js v5AMQP: https://github.com/amqp-node/amqplib v0EventSource:event_source_fetch: https://github.com/Azure/fetch-event-source v2,event_source_express: https://github.com/expressjs/express v4HTTP: none β uses the globalfetchbuilt into Node.js 18+ (the generated client relies on the nativefetch/Headers; swap innode-fetch,axios, etc. via themakeRequesthook if needed)WebSocket: https://github.com/websockets/ws v8
For TypeScript, the generator creates one file per protocol plus an index file that re-exports all protocols as namespaces. For example;
// Import specific functions from a protocol file
import {
jetStreamPublishToSendUserSignedup,
subscribeToReceiveUserSignedup,
publishToSendUserSignedup
} from 'src/__gen__/nats';
// Or import the entire protocol namespace
import * as nats from 'src/__gen__/nats';
// Or import all protocols from the index
import { nats, kafka, mqtt, amqp, event_source } from 'src/__gen__/index';
The generated file structure is:
outputPath/
βββ index.ts # Re-exports all protocol namespaces
βββ nats.ts # NATS-specific functions
βββ kafka.ts # Kafka-specific functions
βββ mqtt.ts # MQTT-specific functions
βββ amqp.ts # AMQP-specific functions
βββ event_source.ts # EventSource-specific functions
βββ http_client.ts # HTTP client-specific functions
βββ websocket.ts # WebSocket-specific functions
Each protocol file contains standalone exported functions for interacting with channels defined in your AsyncAPI document.
Organizationβ
The organization option controls how the generated functions are surfaced in the barrel index.ts. The per-protocol <protocol>.ts files are identical across every style β only the re-export shape changes, so switching styles never changes the generated function code.
| Value | Behavior |
|---|---|
flat (default) | Every function is re-exported directly under its protocol namespace. Byte-identical to previous versions. |
tag | Functions are grouped under their API tag. |
path | Functions are nested by their URL path / channel address segments. |
flat (default)β
import { http_client } from './channels';
await http_client.updatePet({ /* ... */ });
tagβ
Functions are grouped one level deep under their first tag. Leaf names are kept verbatim (the operationId / generated function name is unchanged).
- OpenAPI: the tag comes from the operation's
tags. - AsyncAPI: the tag comes from the operation's
tagsfirst; if the operation has none, the (AsyncAPI v3-only) channeltagsare used. AsyncAPI v2 channels have no tags. Functions with no resolvable tag fall into anuntaggedbucket.
import { http_client } from './channels';
await http_client.pet.updatePet({ /* ... */ }); // OpenAPI, grouped by tag "pet"
import { nats } from './channels';
await nats.user.publishToSendUserSignedup({ /* ... */ }); // AsyncAPI operation tagged "user"
await nats.untagged.publishToSendSystemPing({ /* ... */ }); // operation with no tag
pathβ
Functions are nested through the static segments of the URL path (OpenAPI) or channel address (AsyncAPI); {parameter} placeholders and empty segments are dropped. The leaf differs by input:
- OpenAPI: the leaf is the lowercased HTTP method (so
POST /petandPUT /petcoexist aspet.postandpet.put). - AsyncAPI: the leaf is a clean action verb derived from the function type β
publish,subscribe,request,reply,jetStreamPublish,jetStreamPullSubscribe,jetStreamPushSubscribe, etc. β mirroring the OpenAPI method leaf (an address has no HTTP method). If two functions would resolve to the same leaf at the same node, the second falls back to its full function name so nothing is ever dropped.
import { http_client } from './channels';
await http_client.pet.put({ /* ... */ }); // PUT /pet
await http_client.pet.findByStatus.get({ /* ... */ }); // GET /pet/findByStatus/{status}/{categoryId}
import { nats } from './channels';
await nats.user.signedup.publish({ /* ... */ }); // address user/signedup/{id}
await nats.user.signedup.jetStreamPublish({ /* ... */ });
Configure it per channels generator:
{
preset: 'channels',
outputPath: './src/__gen__/channels',
protocols: ['http_client'],
organization: 'tag' // 'flat' | 'tag' | 'path'
}