You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: apps/generator/docs/generator-template.md
+75-65Lines changed: 75 additions & 65 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ Suppose you can only sleep when the AC in your bedroom is set to 22 °C, and you
9
9
10
10
In this tutorial:
11
11
12
-
- 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.
12
+
- 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.
13
13
- You'll use [Python Paho-MQTT](https://pypi.org/project/paho-mqtt/) as the **MQTT client** in this project.
14
14
- 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.
15
15
- Lastly, create a reusable component for the output code's `sendTemperatureDrop` and `sendTemperatureRise` functions.
@@ -44,7 +44,7 @@ Before you create the template, you'll need to have an [AsyncAPI document](https
44
44
45
45
``` yml
46
46
47
-
asyncapi: 2.6.0
47
+
asyncapi: 3.0.1
48
48
49
49
info:
50
50
title: Temperature Service
@@ -53,22 +53,26 @@ info:
53
53
54
54
servers:
55
55
dev:
56
-
url: test.mosquitto.org #in case you're using local mosquitto instance, change this value to localhost.
56
+
host: test.mosquitto.org #in case you're using local mosquitto instance, change this value to localhost.
57
57
protocol: mqtt
58
58
59
59
channels:
60
-
temperature/changed:
61
-
description: Updates the bedroom temperature in the database when the temperatures drops or goes up.
62
-
publish:
63
-
operationId: temperatureChange
64
-
message:
60
+
temperatureChanged:
61
+
address: temperature/changed
62
+
messages:
63
+
temperatureChange:
65
64
description: Message that is being sent when the temperature in the bedroom changes.
66
65
payload:
67
-
type: object
68
-
additionalProperties: false
69
-
properties:
70
-
temperatureId:
71
-
type: string
66
+
$ref: '#/components/schemas/temperatureId'
67
+
description: Updates the bedroom temperature in the database when the temperatures drops or goes up.
68
+
69
+
operations:
70
+
temperatureChange:
71
+
action: receive
72
+
summary: Message sent to the broker when the temperature is changed.
73
+
channel:
74
+
$ref: '#/channels/temperatureChanged'
75
+
72
76
components:
73
77
schemas:
74
78
temperatureId:
@@ -112,8 +116,8 @@ The **package.json** file is used to define the dependencies for your template.
112
116
"version": "0.0.1",
113
117
"description": "A template that generates a Python MQTT client using MQTT.",
114
118
"generator": {
115
-
"apiVersion": "v1",
116
-
"generator": ">=1.10.0 <2.0.0",
119
+
"apiVersion": "v3",
120
+
"generator": ">=2.0.0 <4.0.0",
117
121
"supportedProtocols": ["mqtt"]
118
122
},
119
123
"dependencies": {
@@ -326,8 +330,8 @@ In **package.json** you can have the scripts property that you invoke by calling
326
330
"test": "npm run test:clean && npm run test:generate && npm run test:start"
327
331
},
328
332
"generator": {
329
-
"apiVersion": "v1",
330
-
"generator": ">=1.10.0 <2.0.0",
333
+
"apiVersion": "v3",
334
+
"generator": ">=2.0.0 <4.0.0",
331
335
"supportedProtocols": ["mqtt"]
332
336
},
333
337
"dependencies": {
@@ -357,7 +361,7 @@ You often have different runtime environments in programming, e.g., development
357
361
```yml
358
362
servers:
359
363
dev:
360
-
url: test.mosquitto.org
364
+
host: test.mosquitto.org
361
365
protocol: mqtt
362
366
```
363
367
@@ -391,7 +395,7 @@ Update your `test:generate` script in **package.json** to include the server par
You can now replace the static broker from `mqttBroker = 'test.mosquitto.org'` to `mqttBroker = "${asyncapi.servers().get(params.server).url()}"`in**index.js**.
398
+
You can now replace the static broker from `mqttBroker = 'test.mosquitto.org'` to `mqttBroker = "${asyncapi.servers().get(params.server).host()}"`in**index.js**.
@@ -483,23 +487,23 @@ class TemperatureServiceClient:
483
487
484
488
```
485
489
486
-
You'll then need to template to dynamically generate `sendTemperatureDrop` and `sendTemperatureRise` functions in the generated code based off the AsyncAPI document content. The goal is to write template code that returns functions for channels that the Temperature Service application is subscribed to. The template code to generate these functions will look like this:
490
+
You'll then need a template to dynamically generate `sendTemperatureDrop` and `sendTemperatureRise` functions in the generated code based off the AsyncAPI document content. The goal is to write template code that returns functions for operations marked with `action: receive`, using their associated channels. The template code to generate these functions will look like this:
It's recommended to put reusable components outside the template directory in a new directory called components. You'll create a component that will dynamically generate functions in the output for as many channels as there are in your AsyncAPI document that contains a `publish` operation. Add the following code in the **python-mqtt-client-template/components/TopicFunction.js** file, after creating the **python-mqtt-client-template/components/** directory:
498
+
It's recommended to put reusable components outside the template directory in a new directory called components. You'll create a component that will dynamically generate functions in the output for as many operations as there are in your AsyncAPI document that are marked with `action: receive`. Add the following code in the **python-mqtt-client-template/components/TopicFunction.js** file, after creating the **python-mqtt-client-template/components/** directory:
495
499
496
500
```js
497
501
/*
498
502
* This component returns a block of functions that user can use to send messages to specific topic.
499
-
* As input it requires a list of Channel models from the parsed AsyncAPI document
503
+
* As input it requires a list of Operation models from the parsed AsyncAPI document marked with `action: receive`.
500
504
*/
501
-
export function TopicFunction({ channels }) {
502
-
const topicsDetails = getTopics(channels);
505
+
export function TopicFunction({ operations }) {
506
+
const topicsDetails = getTopics(operations);
503
507
let functions = '';
504
508
505
509
topicsDetails.forEach((t) => {
@@ -518,25 +522,28 @@ export function TopicFunction({ channels }) {
518
522
*
519
523
* As input it requires a list of Channel models from the parsed AsyncAPI document
`{ channels }`: the `TopicFunction` component accepts a custom prop called channels and in your template code
539
-
`getTopics(channels)`: Returns a list of objects, one for each channel with two properties; name and topic. The **name** holds information about the `operationId` provided in the AsyncAPI document while the **topic** holds information about the address of the topic.
545
+
`{ operations }`: the `TopicFunction` component accepts a custom prop called operations and in your template code
546
+
`getTopics(operations)`: Returns a list of objects, one for each operation with two properties; name and topic. The **name** holds information about the `operationId` provided in the AsyncAPI document (or a generated ID if operationId is not set) while the **topic** holds information about the address of the topic from the operation's associated channel.
540
547
541
548
Import the `TopicFunction` component in your template code in**index.js** and add the template code to generate the functions to topics that the `Temperature Service` application is subscribed to. In your case, the final version of your template code should look like this:
Run `npm test` on your terminal to ensure everything works as expected.
589
596
590
-
In the next section, you'll add another channel to **asyncapi.yml** file called `temperature/dropped` and `temperature/risen`then run the template again to make sure it still works as expected.
597
+
In the next section, you'll add another channel to **asyncapi.yml** file called `temperatureDropped` and `temperatureRisen` then run the template again to make sure it still works as expected.
591
598
592
599
#### 5d. Update AsyncAPI document
593
600
594
601
Update the AsyncAPI document to use two channels:
595
602
596
603
```yml
597
604
channels:
598
-
temperature/dropped:
599
-
description: Notifies the user when the temperature drops past a certain point.
600
-
publish:
601
-
operationId: temperatureDrop
602
-
message:
605
+
temperatureDropped:
606
+
address: temperature/dropped
607
+
messages:
608
+
temperatureDrop:
603
609
description: Message that is being sent when the temperature drops past a certain point.
604
610
payload:
605
-
type: object
606
-
additionalProperties: false
607
-
properties:
608
-
temperatureId:
609
-
type: string
610
-
611
-
temperature/risen:
612
-
description: Notifies the user when the temperature rises past a certain point.
613
-
publish:
614
-
operationId: temperatureRise
615
-
message:
611
+
$ref: '#/components/schemas/temperatureId'
612
+
description: Notifies the user when the temperature drops past a certain point.
613
+
temperatureRisen:
614
+
address: temperature/risen
615
+
messages:
616
+
temperatureRise:
616
617
description: Message that is being sent when the temperature rises past a certain point.
617
618
payload:
618
-
type: object
619
-
additionalProperties: false
620
-
properties:
621
-
temperatureId:
622
-
type: string
619
+
$ref: '#/components/schemas/temperatureId'
620
+
description: Notifies the user when the temperature rises past a certain point.
621
+
622
+
operations:
623
+
temperatureDrop:
624
+
action: receive
625
+
summary: Message sent to the broker when the temperature is dropped.
626
+
channel:
627
+
$ref: '#/channels/temperatureDropped'
628
+
temperatureRise:
629
+
action: receive
630
+
summary: Message sent to the broker when the temperature is risen.
631
+
channel:
632
+
$ref: '#/channels/temperatureRisen'
623
633
```
624
634
625
635
And update your test script in test.py to test the two functions as below:
@@ -644,6 +654,6 @@ Temperature rise detected 66943992 sent to temperature/risen
644
654
645
655
Great job completing this tutorial! You have learnt how to use an AsyncAPI file to create a Python MQTT template and used it with the Paho-MQTT library in Python to connect to an MQTT broker and publish messages.😃
646
656
647
-
If you want to tinker with a completed template and see what it would look like in production, check out the [Paho-MQTT template](https://github.com/derberg/python-mqtt-client-template/tree/v1.0.0). You can also check out the accompanying [article about creating MQTT client code](https://www.brainfart.dev/blog/asyncapi-codegen-python).
657
+
If you want to tinker with a completed template and see what it would look like in production, check out the [Paho-MQTT template](https://github.com/Harsh16gupta/asyncapi-v3-template-final).
648
658
649
659
You can also check out the [MQTT beginners guide](https://medium.com/python-point/mqtt-basics-with-python-examples-7c758e605d4) tutorial to learn more about asynchronous messaging using MQTT.
0 commit comments