This issue will be the main topic for discussion regarding what this plugin should contain and how.
Everyone is welcomed to contribute, i didn't have yet much time to set up some PR guidelines but soon i will, meanwhile i would like to hear how you guys imagine seeing async api integrated with Nestjs. What i'm doing right now is creating a similar API as nestjs swagger module offers but there are a few differences that we needed to address in different ways with the Async API specification
Channels
AsyncAPI tell us that a channel must be a sort of component that relates with the server, therefore i decided to create 2 decorators for controller methods that will enforce the developer to specify the channel name and payload type but i'll show in a second what i mean by "specifying". A channel is basically what we call a "pattern" in nestjs microservices, i could read the pattern from the decorator but that can take away the possibility to use HTTP controller (async api also does support REST) so i would like to hear ideas on how to approach this in a gentle way.
Since channels are the patterns i will ask for the name of the channel (i could have a decorator with the name but that's just extra boilerplate) and therefore you must guarantee that the channel is valid, there's no way of referencing it yet.
The type will pretty much work as Swagger, you can pass a DTO (but here i hope i can support generics which is something it lacks), and depending on the decorator (Consumer = Subscribe or Publisher = Publish) it will be the message payload
A side book regarding why the channel is not a decorator for the controller class is because there are use cases where your controller can handle multiple patterns and having a channel per controller would restrict that, therefore i decided that each method/event handler will assume the responsibility of providing the channel name
Publisher/Consumer (duplex support)
This one is pretty much straightforward, I have in mind to allow a microservice handler to consume and publish, you still need to specify the name of the channel aka pattern and in this matter it makes more sense having the channel name being specified because it will probably not publish the event to the same channel (in cases like RabbitMQ it does send back the response to the same endpoint but you can also publish to a different broker/channel)
Schema References
AsyncAPI allows you to create custom schema models but this is not 100% like OpenAPI, therefore I will support the reference name as string and custom class type (It has to be decorated with AsyncSchema decorator in order to gather its metadata)
Validations out-of-the-box
If you have used AsyncAPI before it throws usually a lot of generic errors even for things such as "invalid URLs". I decided to add some custom validation wrapped in front of the document/contract builder that will help you identify the mistake, that is something the AsyncAPI team is probably working on at their parser but until then, we'll have some little help
Decorators in mind
Here is a quick overview with the current decorators i do have in mind and settled, this project was already created months ago for personal usage but i decided to look at nestjs swagger module and create a close codebase (so this plugin can be possibly included into an official package and interchanged with swagger decorators)
- AsyncConsumer: Method decorator that generates channel subscribe property (similar to ApiOperation in swagger module)
- AsyncPublisher: Method decorator that generates channel publish property (similar to ApiResponse in swagger)
- AsyncMessage: Class decorator for custom DTO classes that provides extra metadata and tells nestjs async API that its a model to be used as a payload for AsyncConsumer and AsyncPublisher (if the type passed to consumer/publisher does not contain this decorator, it will throw an error)
- AsyncProperty: Property decorator as ApiProperty (swagger module)
The project will be uploaded soon so anyone can contribute, meanwhile I welcome everyone to give some thoughts about this project and help if possible. Let's make our lives easier!