SlideShare a Scribd company logo
1 of 32
Download to read offline
A model-based approach for
developing event-driven
architectures with AsyncAPI
Abel Gómez1, Markel Iglesias-Urkia2, Aitor Urbieta2, Jordi Cabot1,3
1Universitat Oberta de Catalunya, 2Ikerlan, 3ICREA
MODELS conference – April 22, 2020
Subscribe!
Publish!
Broker
An illustrative example
An illustrative example
Iotbox/box1/monitor
An illustrative example
{
"id": "Line A",
"presses":[
{
"id": "Press A1",
"ts": "2020-05-11T18:01:06.158Z",
"value": 10.0
},{
"id": "Press A2",
"ts": "2020-05-11T18:01:06.329Z",
"value": 15.5
}
]
}
An illustrative example
An illustrative example
Iotbox/box1/monitoring
{
"id": "Line A",
"Press A1": {
"ts": "2020-05-11T18:01:06.158Z",
"value": 10.0
},
"Press A2“: {
"ts": "2020-05-11T18:01:06.329Z",
"value": 15.5
}
]
}
Iotbox/box1/monitor
{
"id": "Line A",
"presses":[
{
"id": "Press A1",
"ts": "2020-05-11T18:01:06.158Z",
"value": 10.0
},{
"id": "Press A2",
"ts": "2020-05-11T18:01:06.329Z",
"value": 15.5
}
]
}
It is difficult to maintain consistency:
• Deviations in the topics:
• Lost messages
• Deviations in the message format:
• Information loss
• Runtime problems
Message-driven APIs
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
{
"asyncapi": "2.0.0",
"info": { … },
"servers": {
…
},
"channels": {
…
},
"components": {
…
}
}
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
"info": {
"title": "IoTBox API",
"version": "1.0.0"
},
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
"servers": {
"production": {
"protocol": "mqtt",
"url": "example.com:1883"
}
},
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": ...,
"schema": { "type": "string" }
}
},
"publish": { ... },
"subscribe": { ... }
}
},
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
"publish": {
"operationId": "publishStatus",
"message": {
"$ref": "#/components/messages/statusMessage"
}
},
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
"components": {
"messages": {
…
},
"schemas": {
…
}
}
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": {
"$ref": "#/components/schemas/lineInfo"
}
}
},
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": {
"$ref": "#/components/schemas/pressInfo“
}
}
}
},
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
{
"asyncapi": "2.0.0",
"info": { "title": "IoTBox API", "version": "1.0.0”},
"servers": {
"production": { "protocol": "mqtt", "url": "example.com:1883" }
},
"channels": {
"iotbox/{id}/monitor": {
"parameters": {
"id": {
"description": "The ID of the IoTBox",
"schema": { "type": "string" }
}
},
"publish": {
"operationId": "publishStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
},
"subscribe": {
"operationId": "subscribeStatus",
"message": { "$ref": "#/components/messages/statusMessage" }
}
}
},
"components": {
"messages": {
"statusMessage": {
"description": "Status of a given subsystem",
"payload": { "$ref": "#/components/schemas/lineInfo" }
}
},
"schemas": {
"lineInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the subsystem"
},
"presses": {
"type": "array",
"description": "Info of presses in this subsystem",
"items": { "$ref": "#/components/schemas/pressInfo" }
}
}
},
"pressInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Identifier of the press"
},
"ts": {
"type": "string",
"title": "Timestamp"
},
"value": {
"type": "number",
"description": "Pressure of the press in Pascals"
}
}
}
}
}
}
AsyncAPI toolkit
A model-based approach for developing
event-driven architectures with AsyncAPI
AsyncAPI toolkit
A grammar for the AsyncAPI specification
AsyncAPI:
{AsyncAPI} '{‘ (
( '"asyncapi"' ':' version=VersionNumber ','? )
& ( '"info"' ':' info=Info ','? )
& ( '"servers"' ':' '{' servers+=Server (',' servers+=Server)* '}' ','? )?
& ( '"channels"' ':' '{' channels+=Channel (',' channels+=Channel)* '}' ','? )?
& ( '"components"' ':' components=Components ','? )?
) '}';
Info:
{Info} '{' (
( '"title"' ':' title=AnyString ','? )
& ( '"version"' ':' version=AnyString ','? )
& ( '"description"' ':' description=AnyString ','? )?
& ( '"termsOfService"' ':' termsOfService=AnyString ','? )?
& ( '"contact"' ':' contact=Contact ','? )?
& ( '"license"' ':' license=License ','? )?
) '}';
A grammar for the AsyncAPI specification
A metamodel for the AsyncAPI specification
Defining an event-driven architecture
Equivalent API model
The generated code
The generated code
package main;
import java.time.Instant;
import iotbox._id_.monitor.PublishStatus;
import iotbox._id_.monitor.PublishStatus.PublishStatusParams;
import schemas.LineInfo;
import schemas.PressInfo;
public class Publish {
public static void main(String[] args) throws Exception {
LineInfo payload = LineInfo.newBuilder()
.withId("Line A")
.addToPresses(
PressInfo.newBuilder()
.withId("Press A1")
.withTimestamp(Instant.now().toString())
.withValue(10.0)
.build()
)
.addToPresses(
PressInfo.newBuilder()
.withId("Press A2")
.withTimestamp(Instant.now().toString())
.withValue(15.5)
.build()
)
.build();
PublishStatusParams params = PublishStatusParams.create().withId("box1");
PublishStatus.publish(payload, params);
}
}
{
"id": "Line A",
"presses": [
{
"id": "Press A1",
"ts": "2020-05-11T18:01:06.158Z",
"value": 10.0
},{
"id": "Press A2",
"ts": "2020-05-11T18:01:06.329Z",
"value": 15.5
}
]
}
• With AsyncAPI Toolkit, an AsyncAPI specification is the singlesource
of truthwhen designing and running an event-driven architecture.
• The AsyncAPI Toolkit leverages model-based techniques for:
• lower development and deployment time;
• better code quality;
• increased maintanability
• better requirements management;
• better documentation.
Summary and conclusions
We see AsyncAPI Toolkit as a toolkit able to support most
phasesof the development cycle, from requirementsto
code-generation to —in the future— testing.
—Ikerlan
UOCresearch
@UOC_research
https://github.com/SOM-Research/asyncapi-toolkit
agomezlla@uoc.edu

More Related Content

Similar to A model based approach for developing event-driven architectures with AsyncAPI

201410 2 fiware-orion-contextbroker
201410 2 fiware-orion-contextbroker201410 2 fiware-orion-contextbroker
201410 2 fiware-orion-contextbroker
FIWARE
 
Events Processing and Data Analysis with Lucidworks Fusion: Presented by Kira...
Events Processing and Data Analysis with Lucidworks Fusion: Presented by Kira...Events Processing and Data Analysis with Lucidworks Fusion: Presented by Kira...
Events Processing and Data Analysis with Lucidworks Fusion: Presented by Kira...
Lucidworks
 

Similar to A model based approach for developing event-driven architectures with AsyncAPI (20)

[OpenInfra Days Korea 2018] (Track 4) CloudEvents 소개 - 상호 운용 가능성을 극대화한 이벤트 데이...
[OpenInfra Days Korea 2018] (Track 4) CloudEvents 소개 - 상호 운용 가능성을 극대화한 이벤트 데이...[OpenInfra Days Korea 2018] (Track 4) CloudEvents 소개 - 상호 운용 가능성을 극대화한 이벤트 데이...
[OpenInfra Days Korea 2018] (Track 4) CloudEvents 소개 - 상호 운용 가능성을 극대화한 이벤트 데이...
 
FIWARE Global Summit - The Way Towards Interoperability between Web Of Things...
FIWARE Global Summit - The Way Towards Interoperability between Web Of Things...FIWARE Global Summit - The Way Towards Interoperability between Web Of Things...
FIWARE Global Summit - The Way Towards Interoperability between Web Of Things...
 
Winning with Structured Data and Schema.org - OMLIVE 2018
Winning with Structured Data and Schema.org - OMLIVE 2018Winning with Structured Data and Schema.org - OMLIVE 2018
Winning with Structured Data and Schema.org - OMLIVE 2018
 
Cloud Adoption in Regulated Financial Services - SID328 - re:Invent 2017
Cloud Adoption in Regulated Financial Services - SID328 - re:Invent 2017Cloud Adoption in Regulated Financial Services - SID328 - re:Invent 2017
Cloud Adoption in Regulated Financial Services - SID328 - re:Invent 2017
 
Closing the Loop in Extended Reality with Kafka Streams and Machine Learning ...
Closing the Loop in Extended Reality with Kafka Streams and Machine Learning ...Closing the Loop in Extended Reality with Kafka Streams and Machine Learning ...
Closing the Loop in Extended Reality with Kafka Streams and Machine Learning ...
 
Elasticsearch for SQL Users
Elasticsearch for SQL UsersElasticsearch for SQL Users
Elasticsearch for SQL Users
 
FIWARE Developers Week_ Introduction to Managing Context Information at Large...
FIWARE Developers Week_ Introduction to Managing Context Information at Large...FIWARE Developers Week_ Introduction to Managing Context Information at Large...
FIWARE Developers Week_ Introduction to Managing Context Information at Large...
 
Consuming APIs with Python
Consuming APIs with PythonConsuming APIs with Python
Consuming APIs with Python
 
Integrate CI/CD Pipelines with Jira Software Cloud
Integrate CI/CD Pipelines with Jira Software CloudIntegrate CI/CD Pipelines with Jira Software Cloud
Integrate CI/CD Pipelines with Jira Software Cloud
 
Couchbase presentation - by Patrick Heneise
Couchbase presentation - by Patrick HeneiseCouchbase presentation - by Patrick Heneise
Couchbase presentation - by Patrick Heneise
 
AWS CloudFormation Session
AWS CloudFormation SessionAWS CloudFormation Session
AWS CloudFormation Session
 
201410 2 fiware-orion-contextbroker
201410 2 fiware-orion-contextbroker201410 2 fiware-orion-contextbroker
201410 2 fiware-orion-contextbroker
 
Events Processing and Data Analysis with Lucidworks Fusion: Presented by Kira...
Events Processing and Data Analysis with Lucidworks Fusion: Presented by Kira...Events Processing and Data Analysis with Lucidworks Fusion: Presented by Kira...
Events Processing and Data Analysis with Lucidworks Fusion: Presented by Kira...
 
B 3 line bot live coding
B 3 line bot live codingB 3 line bot live coding
B 3 line bot live coding
 
Building and Scaling the Internet of Things with MongoDB at Vivint
Building and Scaling the Internet of Things with MongoDB at Vivint Building and Scaling the Internet of Things with MongoDB at Vivint
Building and Scaling the Internet of Things with MongoDB at Vivint
 
InfluxData Webinar 16 June, 2020 - How to Create a Telegraf Parser Plugin for...
InfluxData Webinar 16 June, 2020 - How to Create a Telegraf Parser Plugin for...InfluxData Webinar 16 June, 2020 - How to Create a Telegraf Parser Plugin for...
InfluxData Webinar 16 June, 2020 - How to Create a Telegraf Parser Plugin for...
 
ELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboardELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboard
 
Montreal Elasticsearch Meetup
Montreal Elasticsearch MeetupMontreal Elasticsearch Meetup
Montreal Elasticsearch Meetup
 
Implementing and Visualizing Clickstream data with MongoDB
Implementing and Visualizing Clickstream data with MongoDBImplementing and Visualizing Clickstream data with MongoDB
Implementing and Visualizing Clickstream data with MongoDB
 
Gov APIs: The Notorious Case of Official Statistics
Gov APIs: The Notorious Case of Official StatisticsGov APIs: The Notorious Case of Official Statistics
Gov APIs: The Notorious Case of Official Statistics
 

More from abgolla

More from abgolla (6)

A Modeling Editor and Code Generator for AsyncAPI
A Modeling Editor and Code Generator for AsyncAPIA Modeling Editor and Code Generator for AsyncAPI
A Modeling Editor and Code Generator for AsyncAPI
 
Enabling Performance Modeling for the Masses: Initial Experiences
Enabling Performance Modeling for the Masses: Initial ExperiencesEnabling Performance Modeling for the Masses: Initial Experiences
Enabling Performance Modeling for the Masses: Initial Experiences
 
TemporalEMF: A Temporal Metamodeling Framework
TemporalEMF: A Temporal Metamodeling FrameworkTemporalEMF: A Temporal Metamodeling Framework
TemporalEMF: A Temporal Metamodeling Framework
 
On the Opportunities of Scalable Modeling Technologies: An Experience Report ...
On the Opportunities of Scalable Modeling Technologies: An Experience Report ...On the Opportunities of Scalable Modeling Technologies: An Experience Report ...
On the Opportunities of Scalable Modeling Technologies: An Experience Report ...
 
Una herramienta para evaluar el rendimiento de aplicaciones intensivas en datos
Una herramienta para evaluar el rendimiento de aplicaciones intensivas en datosUna herramienta para evaluar el rendimiento de aplicaciones intensivas en datos
Una herramienta para evaluar el rendimiento de aplicaciones intensivas en datos
 
Fase 2015 - Map-based Transparent Persistence for Very Large Models
Fase 2015 - Map-based Transparent Persistence for Very Large ModelsFase 2015 - Map-based Transparent Persistence for Very Large Models
Fase 2015 - Map-based Transparent Persistence for Very Large Models
 

Recently uploaded

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 

Recently uploaded (20)

Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 

A model based approach for developing event-driven architectures with AsyncAPI

  • 1. A model-based approach for developing event-driven architectures with AsyncAPI Abel Gómez1, Markel Iglesias-Urkia2, Aitor Urbieta2, Jordi Cabot1,3 1Universitat Oberta de Catalunya, 2Ikerlan, 3ICREA MODELS conference – April 22, 2020
  • 3.
  • 6. Iotbox/box1/monitor An illustrative example { "id": "Line A", "presses":[ { "id": "Press A1", "ts": "2020-05-11T18:01:06.158Z", "value": 10.0 },{ "id": "Press A2", "ts": "2020-05-11T18:01:06.329Z", "value": 15.5 } ] }
  • 8. An illustrative example Iotbox/box1/monitoring { "id": "Line A", "Press A1": { "ts": "2020-05-11T18:01:06.158Z", "value": 10.0 }, "Press A2“: { "ts": "2020-05-11T18:01:06.329Z", "value": 15.5 } ] } Iotbox/box1/monitor { "id": "Line A", "presses":[ { "id": "Press A1", "ts": "2020-05-11T18:01:06.158Z", "value": 10.0 },{ "id": "Press A2", "ts": "2020-05-11T18:01:06.329Z", "value": 15.5 } ] }
  • 9. It is difficult to maintain consistency: • Deviations in the topics: • Lost messages • Deviations in the message format: • Information loss • Runtime problems Message-driven APIs
  • 10.
  • 11. { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 12. { "asyncapi": "2.0.0", "info": { … }, "servers": { … }, "channels": { … }, "components": { … } } { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 13. "info": { "title": "IoTBox API", "version": "1.0.0" }, { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 14. "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 15. "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": ..., "schema": { "type": "string" } } }, "publish": { ... }, "subscribe": { ... } } }, { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 16. "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 17. "components": { "messages": { … }, "schemas": { … } } { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 18. "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 19. "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo“ } } } }, { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 20. "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } { "asyncapi": "2.0.0", "info": { "title": "IoTBox API", "version": "1.0.0”}, "servers": { "production": { "protocol": "mqtt", "url": "example.com:1883" } }, "channels": { "iotbox/{id}/monitor": { "parameters": { "id": { "description": "The ID of the IoTBox", "schema": { "type": "string" } } }, "publish": { "operationId": "publishStatus", "message": { "$ref": "#/components/messages/statusMessage" } }, "subscribe": { "operationId": "subscribeStatus", "message": { "$ref": "#/components/messages/statusMessage" } } } }, "components": { "messages": { "statusMessage": { "description": "Status of a given subsystem", "payload": { "$ref": "#/components/schemas/lineInfo" } } }, "schemas": { "lineInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the subsystem" }, "presses": { "type": "array", "description": "Info of presses in this subsystem", "items": { "$ref": "#/components/schemas/pressInfo" } } } }, "pressInfo": { "type": "object", "properties": { "id": { "type": "string", "description": "Identifier of the press" }, "ts": { "type": "string", "title": "Timestamp" }, "value": { "type": "number", "description": "Pressure of the press in Pascals" } } } } } }
  • 21.
  • 22. AsyncAPI toolkit A model-based approach for developing event-driven architectures with AsyncAPI
  • 24. A grammar for the AsyncAPI specification
  • 25. AsyncAPI: {AsyncAPI} '{‘ ( ( '"asyncapi"' ':' version=VersionNumber ','? ) & ( '"info"' ':' info=Info ','? ) & ( '"servers"' ':' '{' servers+=Server (',' servers+=Server)* '}' ','? )? & ( '"channels"' ':' '{' channels+=Channel (',' channels+=Channel)* '}' ','? )? & ( '"components"' ':' components=Components ','? )? ) '}'; Info: {Info} '{' ( ( '"title"' ':' title=AnyString ','? ) & ( '"version"' ':' version=AnyString ','? ) & ( '"description"' ':' description=AnyString ','? )? & ( '"termsOfService"' ':' termsOfService=AnyString ','? )? & ( '"contact"' ':' contact=Contact ','? )? & ( '"license"' ':' license=License ','? )? ) '}'; A grammar for the AsyncAPI specification
  • 26. A metamodel for the AsyncAPI specification
  • 27. Defining an event-driven architecture
  • 30. The generated code package main; import java.time.Instant; import iotbox._id_.monitor.PublishStatus; import iotbox._id_.monitor.PublishStatus.PublishStatusParams; import schemas.LineInfo; import schemas.PressInfo; public class Publish { public static void main(String[] args) throws Exception { LineInfo payload = LineInfo.newBuilder() .withId("Line A") .addToPresses( PressInfo.newBuilder() .withId("Press A1") .withTimestamp(Instant.now().toString()) .withValue(10.0) .build() ) .addToPresses( PressInfo.newBuilder() .withId("Press A2") .withTimestamp(Instant.now().toString()) .withValue(15.5) .build() ) .build(); PublishStatusParams params = PublishStatusParams.create().withId("box1"); PublishStatus.publish(payload, params); } } { "id": "Line A", "presses": [ { "id": "Press A1", "ts": "2020-05-11T18:01:06.158Z", "value": 10.0 },{ "id": "Press A2", "ts": "2020-05-11T18:01:06.329Z", "value": 15.5 } ] }
  • 31. • With AsyncAPI Toolkit, an AsyncAPI specification is the singlesource of truthwhen designing and running an event-driven architecture. • The AsyncAPI Toolkit leverages model-based techniques for: • lower development and deployment time; • better code quality; • increased maintanability • better requirements management; • better documentation. Summary and conclusions We see AsyncAPI Toolkit as a toolkit able to support most phasesof the development cycle, from requirementsto code-generation to —in the future— testing. —Ikerlan