Code generation #
code command generates the Go boilerplate code with minimal dependencies, representing the AsyncAPI entities such as servers, channels,
operations, bindings, etc. By default, this command also generates the minimal client code for some protocols based on
the popular libraries to be able to work out of the box.
The codegen process is highly customizable in go-asyncapi configuration file:
- Custom layout - the generated code can have literally any structure
- Publish-only or subscribe-only code
- Generation the zero-dependency code – no third-party libraries are used
Code generation is also an important part of Contract-First Development (so-called “API First” or “Schema First”).
See examples directory for more code usage examples.
The generated code can also be customized in templates. See templating guide for more details.
Usage #
All command options are duplicated in configuration file. So, you can set them there as well.
To generate the code with default layout and settings, use the code command:
go-asyncapi code [options...] <asyncapi-document>
The default where to put the generated code (target directory) is ./asyncapi directory. Option -t allows to specify
a different target directory:
go-asyncapi code streetlights-mqtt-asyncapi.yml -t /tmp/my-asyncapi-code
The project module (that is used as base import path in the generated code) is extracted automatically from
go.mod file in current directory, However, if you want to specify it explicitly, use the -M option:
go-asyncapi code -M github.com/my/repo/path streetlights-mqtt-asyncapi.yml
By default, the command processes only local $refs. To allow processing remote $refs, use the --allow-remote-refs option:
go-asyncapi code --allow-remote-refs <asyncapi-document>
To generate code without 3rd-party libraries (implementations), use the --disable-implementations option:
go-asyncapi code --disable-implementations <asynapi-document>
To enable the debug logging output, use -v=1 flag, and use the -v=2 flag to enable the trace logging output:
go-asyncapi code streetlights-mqtt-asyncapi.yml -v=1
Design overview #
The code generated by go-asyncapi roughly follows the AsyncAPI specification structure, but it is not a 1:1 mapping.
On the figure below it’s shown what the code looks like from high level.
Roughly speaking, the generated code consists of four parts:
- Go types that are generated separately for every protocol it is bound to (channel, operation, etc.)
- Go types that are generated once (message, model, etc.)
- Optional implementation code for protocol used in the AsyncAPI document
- Protocol-specific utility code (interfaces, util types, etc.)
The structure of types is shown below.
This approach reminds the Bridge pattern. We have an abstraction layer, that follows the AsyncAPI entities, and implementation layer, which can be chosen or replaced without affecting the abstractions.
These layers are isolated from each other via Go interfaces:
Producer/Consumerinterface represents the “network connection” to a message broker or peer, and it is supposed to contain “channels”Publisher/Subscriberinterface represents a “channel” inside a “connection”, and is used to send/receive messages through itEnvelopeWriter/EnvelopeReaderinterface is used to marshal/unmarshal protocol-specific envelopes from/to messages
go-asyncapi has built-in implementations for several popular protocols, which are already using this model. But if
you want to use your own code, all you need to do is to implement these interfaces. See example for more details.
This is quite generic model, but it allows to implement different protocols with different semantics and capabilities using the same interface. Many protocols fit well to this model (like Kafka, MQTT, etc.), others may not have a clear distinction between connection and channel (like TCP). Specifically for such protocols, the implementation code may treat connection as channel and do nothing on connection creation.
Runtime package #
The only external dependency that always required in the generated code is the package called the runtime package.
It is a part of go-asyncapi project and contains some widely reusable util code.
The reason this package is external to the generated code is to reduce the amount of generated code and simplify the code generation process.
By default, it is github.com/bdragon300/go-asyncapi/run, which is also configurable.