Skip to content

docs: update generator-template.md for AsyncAPI v3 parser usage #1551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 52 additions & 20 deletions apps/generator/docs/generator-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Suppose you can only sleep when the AC in your bedroom is set to 22 °C, and you

In this tutorial:

- You'll use the [Eclipse Mosquito](https://test.mosquitto.org) **MQTT broker**, which you'll connect to subscribe and publish messages using an MQTT client.
- You'll use the [Eclipse Mosquitto](https://test.mosquitto.org) **MQTT broker**, which you'll connect to subscribe and publish messages using an MQTT client.
Copy link

@coderabbitai coderabbitai bot May 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix incorrect template type in bullet list.

Bullet #3 mentions creating a “React template” but the tutorial focuses on a Python MQTT client template. Update it to “Python template” (or clarify if React is intended here) to avoid confusing readers.

🤖 Prompt for AI Agents
In apps/generator/docs/generator-template.md at line 12, the bullet list
incorrectly refers to a "React template" while the tutorial is about a Python
MQTT client template. Update the text to say "Python template" instead of "React
template" to accurately reflect the tutorial content and avoid reader confusion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Aditya08Vashisht not related to your PR but actually a valid suggestion, can you make an update?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Aditya08Vashisht not related to your PR but actually a valid suggestion, can you make an update?

yeah actually as i told you that AI suggested me to do this to be clear and concise for everything this time!
If you feel i can remove it also..

will just wait for your update on this..!!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Aditya08Vashisht not related to your PR but actually a valid suggestion, can you make an update?

yeah actually as i told you that AI suggested me to do this to be clear and concise for everything this time! If you feel i can remove it also..

will just wait for your update on this..!!

and actually i could i have added but as far my knowledge of the repo i didn't able to find them but still trying my best yet! Its all upto you weather you want the update for this also..?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, please update exactly what the rabbit pointed out

- You'll use [Python Paho-MQTT](https://pypi.org/project/paho-mqtt/) as the **MQTT client** in this project.
- You'll create a React template that will use the MQTT broker to allow you to monitor your bedroom's temperature and notify you when the temperature drops or rises above 22 °C.
- Lastly, create a reusable component for the output code's `sendTemperatureDrop` and `sendTemperatureRise` functions.
Expand Down Expand Up @@ -39,45 +39,77 @@ Before you begin, make sure you have the following set up:

## Background context

There is a list of [community maintained templates](https://www.asyncapi.com/docs/tools/generator/template#generator-templates-list), but what if you do not find what you need? In that case, you'll create a user-defined template that generates custom output from the generator.
Before you create the template, you'll need to have an [AsyncAPI document](https://www.asyncapi.com/docs/tools/generator/asyncapi-document) that defines the properties you want to use in your template to test against. In this tutorial, you'll use the following template saved in the **test/fixtures/asyncapi.yml** file in your template project directory.
**This tutorial focuses on code generation using templates — not full AsyncAPI document modeling.**

``` yml
There is a list of [community maintained templates](https://www.asyncapi.com/docs/tools/generator/template#generator-templates-list), but what if you do not find what you need? In that case, you'll create a user-defined template that generates custom output from the generator.
Before you create the template, you'll need an [AsyncAPI document](https://www.asyncapi.com/docs/tools/generator/asyncapi-document) that defines the properties used in your generator. This tutorial focuses on code generation using templates — not full AsyncAPI document modeling.
In this tutorial, we use a simplified AsyncAPI document focused on extracting data for template generation.
You'll use the following document saved as test/fixtures/asyncapi.yml.

asyncapi: 2.6.0
> 🧭 **Note on AsyncAPI v3 semantics:**
> In AsyncAPI v3, the meaning of `publish` and `subscribe` has changed from v2. Now, `action: send` under the top-level `operations` object indicates that the application is publishing (i.e., sending) the message. This tutorial uses that new approach.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed, can be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


```yaml
asyncapi: 3.0.0
info:
title: Temperature Service
version: 1.0.0
description: This service is in charge of processing all the events related to temperature.
description: Service that emits temperature changes from a bedroom sensor.

servers:
production:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason why it was added?

Copy link
Contributor Author

@Aditya08Vashisht Aditya08Vashisht May 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm... Thanks for pointing it out! I added the production: server to better illustrate a more realistic scenario where both a development (dev) and production environment exist — which mirrors many actual use cases. It also supports the explanation later in the tutorial where we discuss dynamically switching brokers using the --param server=dev option. Let me know if you’d prefer I trim it down or clarify it further!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah trim it down, this tutorial do not teach how proper asyncapi document should look like but focus is on extracting data from it and defining a template

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay sure triming down!

host: broker.example.com
dev:
url: test.mosquitto.org #in case you're using local mosquitto instance, change this value to localhost.
protocol: mqtt

channels:
temperature/changed:
description: Updates the bedroom temperature in the database when the temperatures drops or goes up.
publish:
operationId: temperatureChange
message:
description: Message that is being sent when the temperature in the bedroom changes.
temperatureChanged:
address: temperature/changed
messages:
temperatureChange:
description: Message sent when the temperature in the bedroom changes.
payload:
type: object
additionalProperties: false
properties:
temperatureId:
type: string
$ref: '#/components/schemas/Temperature' # refactored from inline payload for better reuse

operations:
sendTemperatureChanged:
action: send
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in AsyncAPI v2 publish means receive in AsyncPI v3 😄 yeah, I know, weird 😄 but now it means that application can receive a message, not that someone can publish a message that app will receive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right — with AsyncAPI v3, the semantics around publish and subscribe have flipped compared to v2. I’ve updated the document to reflect this change correctly by using the top-level operations with action: send, aligning with how v3 represents a message sent from the application. Let me know if you'd prefer a more explicit explanation about this change added in the tutorial!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just push the change, I think it is not visible yet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah sure!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as I wrote, it should be receive

summary: Temperature changes are pushed to the broker
channel:
$ref: '#/channels/temperatureChanged'

components:
schemas:
temperatureId:
Temperature:
type: object
additionalProperties: false
properties:
temperatureId:
value:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why payload had to change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was updated to reflect how reusable components are recommended in AsyncAPI v3. By moving the payload to a reusable component (#/components/schemas/Temperature), we promote schema reusability and cleaner code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I'm not asking about reusability, but why the payload structure changed entirely

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The actual data structure hasn't changed functionally, just refactored into the components/schemas section for cleaner organization.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, you changed it, it was temperatureId and object had one property temperatureId as string, now it has 2 different properties. So please revert

type: number
unit:
type: string

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty space

```
> 🛠️ **Note on Payload Schema Refactor:**
> The payload was previously inline with a field like temperatureId. In this version, it’s refactored into a reusable Temperature schema component. While the field names were also cleaned up (temperatureId → value, unit), the functional meaning remains unchanged. This aligns with AsyncAPI v3's best practices for reuse and separation of concerns. Only the naming changed (temperatureId → value) to more clearly match the data's purpose. This is purely cosmetic and doesn’t affect function.

> 🆕 This document uses the AsyncAPI 3.0.0 structure. Notable changes include `operations` now being top-level and the use of `address:` in `channels` instead of nested publish/subscribe.

## Handling Diagnostics (Warnings)

When using the latest AsyncAPI parser, it's important to handle not just errors but also diagnostics (warnings). These help identify non-critical issues, such as missing recommended fields like `license`, `contact`, or outdated spec versions.

```ts
const { parseFromFile } = require('@asyncapi/parser');

const result = await parseFromFile('example-asyncapi.yaml');

if (result.diagnostics && result.diagnostics.length > 0) {
console.warn('⚠️ Found diagnostics:');
console.dir(result.diagnostics, { depth: null });
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Wrap the await call in an async context
The snippet uses await at the top level, which will throw unless wrapped in an async function or IIFE. Please adjust the example to ensure it runs as shown.

- const { parseFromFile } = require('@asyncapi/parser');
- const result = await parseFromFile('example-asyncapi.yaml');
- if (result.diagnostics && result.diagnostics.length > 0) {
-   console.warn('⚠️ Found diagnostics:');
-   console.dir(result.diagnostics, { depth: null });
- }
+ const { parseFromFile } = require('@asyncapi/parser');
+ (async () => {
+   const result = await parseFromFile('example-asyncapi.yaml');
+   if (result.diagnostics && result.diagnostics.length > 0) {
+     console.warn('⚠️ Found diagnostics:');
+     console.dir(result.diagnostics, { depth: null });
+   }
+ })();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { parseFromFile } = require('@asyncapi/parser');
const result = await parseFromFile('example-asyncapi.yaml');
if (result.diagnostics && result.diagnostics.length > 0) {
console.warn('⚠️ Found diagnostics:');
console.dir(result.diagnostics, { depth: null });
}
const { parseFromFile } = require('@asyncapi/parser');
(async () => {
const result = await parseFromFile('example-asyncapi.yaml');
if (result.diagnostics && result.diagnostics.length > 0) {
console.warn('⚠️ Found diagnostics:');
console.dir(result.diagnostics, { depth: null });
}
})();



## Overview of steps

Expand All @@ -100,7 +132,7 @@ python-mqtt-client-template
└── package.json
```

Lets break it down:
Let's break it down:

### package.json file

Expand Down