MDSL Home — AsyncMDSL Language Reference — MDSL Tools Overview
AsyncAPI Specification Generator
Note: The status of this generator, contributed by Giacomo Di Liberali, is Technology Preview.
The AsyncMDSL plugin for Eclipse allows API designers to generate AsyncAPI specifications out of AsyncMDSL service contracts.
Usage
You can generate the AsyncAPI specification out of an MDSL model by using the MDSL Eclipse plugin. You will find the generator in the MDSL context menu:
Hint: the output will be created into the src-gen
folder which is located in the projects root directory. Look for .yaml
files corresponding to the .mdsl
input.
AsyncAPI mapping
Each AsyncMDSL concept is mapped to one, or a combination of more specification objects in AsyncAPI:
AsyncMDSL | AsyncAPI | Description |
---|---|---|
Service Specification | AsyncAPI Object, AsyncAPI Version String, AsyncAPI Info Object and Components Object | Each serviceSpecification represent a group of channels, and contains global available information such as the version and a description, and furthermore it is the container of all the other components. |
OneWay Channel | Operation Object | An operation represent a channel, with path, parameters and message schema. In AsyncAPI channels’ names are their paths. |
Request-Reply Channel | A pair of Channel Item Object | A Request-Reply Channel is mapped into a pair of separate channels, each with its own path. |
Channel parameter | Parameter Object | Each object describes a single parameter included in a channel path. |
Message | Message Object | Represent a message that flows through a channel. It provides a place to document how and why messages are produced and consumed. |
Channel binding | Operation Binding Object | Allows the definition of protocol-specific parameters for a Message Channel. |
Broker binding | Server Bindings Object | Allows the definition of protocol-specific parameters for a Message Broker. |
Data types | Schema Object | Allows the definition of input and output data types. |
Correlation Id WhereClause | Correlation ID Object | Specifies an identifier at design time that can used for message tracing and correlation. |
Datatype Type Reference | Reference Object | Allows referencing other data types in the specification. |
Message Broker | Server Object | Represents a Message Broker using a single protocol. If a Message Broker supports multiple protocols, a copy of it will be created for each distinct protocol in a separate .yml file. |
Endpoints | AsyncAPI does not support Message Endpoints. |
Full Example
API description HealthcareExample
version "1.0.0"
data type MeasurementDTO { "id": ID<int>, "type": D<string>, "value": D<double> }
data type HeadersDTO {
"tenantId": ID<int>,
"messageId": ID<string>?,
"apiKey": ID<string>?
}
channel PatientMeasurements
of type PUBLISH_SUBSCRIBE, DATA_TYPE
delivery guarantee AT_LEAST_ONCE
description "Notifies whenever a new measurement comes"
on path "/patients/${patientId}/measurement"
with patientId: int, "The patient identifier"
produces message Measurement
delivering
headers HeadersDTO
payload MeasurementDTO as EVENT_MESSAGE
where
MESSAGE_EXPIRES in 60m
channel EnqueueTask
request message EnqueueTaskRequest
on path "/patients/${patientId}/tasks"
with patientId: int, "The patient identifier"
expecting
headers HeadersDTO
payload P
reply message EnqueueTaskReply
on path "/tasks/${taskId}/complete"
with taskId: int, "The task identifier"
delivering payload P
where
CORRELATION_ID is "$message.header#/messageId"
message broker BrokerExample
description "Expose channels under AMQP"
exposes
EnqueueTask,
PatientMeasurements
at location "amqp.myhealthcare.org"
via protocol AMQP
bindings {
"qos": 1
}
For the AsyncMDSL contract above, the generator produces the following AsyncAPI specification:
asyncapi: '2.0.0'
info:
title: HealthcareExample
version: "1.0.0"
description: |
No description specified
servers:
BrokerExample:
url: amqp.myhealthcare.org
protocol: AMQP
description: Expose channels under AMQP
bindings:
amqp:
qos:
1
channels:
/patients/${patientId}/tasks:
parameters:
patientId:
description: The patient identifier
schema:
type: integer
subscribe:
description: |
No description specified
Delivering guarantee: UNKNOWN.
Request channel. Reply channel is [EnqueueTaskReply](#operation-publish-/tasks/${taskId}/complete)
operationId: enqueueTaskRequest
message:
$ref: '#/components/messages/EnqueueTaskRequest'
/tasks/${taskId}/complete:
parameters:
taskId:
description: The task identifier
schema:
type: integer
publish:
description: |
No description specified
Where:
- CORRELATION_ID is "$message.header#/messageId"
Reply channel. Request channel is [EnqueueTaskRequest](#operation-subscribe-/patients/${patientId}/tasks)
operationId: enqueueTaskReply
message:
$ref: '#/components/messages/EnqueueTaskReply'
/patients/${patientId}/measurement:
parameters:
patientId:
description: The patient identifier
schema:
type: integer
publish:
description: |
Notifies whenever a new measurement comes
Delivering guarantee: AT_LEAST_ONCE.
Where:
- MESSAGE_EXPIRES in 60m
One way channel (does not expect reply).
operationId: measurementPublish
message:
$ref: '#/components/messages/Measurement'
components:
messages:
Measurement:
name: Measurement
title: Measurement
description: |
No description specified
payload:
$ref: '#/components/schemas/MeasurementDTO'
headers:
unnamedParameter24:
$ref: '#/components/schemas/HeadersDTO'
EnqueueTaskRequest:
name: EnqueueTaskRequest
title: Enqueue Task Request
description: |
No description specified
Request message. Reply message is *EnqueueTaskReply*.
payload:
type: object
unnamedParameter25:
type: object
headers:
unnamedParameter26:
$ref: '#/components/schemas/HeadersDTO'
EnqueueTaskReply:
name: EnqueueTaskReply
title: Enqueue Task Reply
description: |
No description specified
Reply message. Request message is *EnqueueTaskRequest*.
correlationId:
location: '$message.header#/messageId'
payload:
type: object
unnamedParameter27:
type: object
schemas:
MeasurementDTO:
type: object
required:
- 'id'
- 'type'
- 'value'
properties:
'id':
type: integer
'type':
type: string
'value':
type: number
HeadersDTO:
type: object
required:
- 'tenantId'
properties:
'tenantId':
type: integer
'messageId':
type: string
'apiKey':
type: string
Validation and code generation
You can use the AsyncAPI Playground to validate generated specifications.
You can also test code generation using the asyncapi/generator running the following command (assuming an asyncapi.yaml
file exists in the current directory), for instance:
docker run --rm -it \
-v ${PWD}/asyncapi.yaml:/app/asyncapi.yml \
-v ${PWD}/output:/app/output \
asyncapi/generator -o ./output asyncapi.yml @asyncapi/html-template --force-write
Once complete, an output
folder will be created in the current directory containing the generated skeleton.
Alternative templates are:
@asyncapi/java-spring-template
@asyncapi/html-template
@asyncapi/nodejs-template
More information on the asyncapi-generator
that we used in this example can be found in its GitHub repository.
Known limitations
- The generator does not support security policies.
- A channel can only transfer messages of one data type.
- The generator does not work when invoked in the Command Line Interface (CLI).
Other Generators
Also checkout our other generators:
- OpenAPI generator
- Protocol Buffers generator
- GraphQL generator
- Java “modulith” generator
- Jolie generator
- Arbitrary textual generation with Freemarker
Site Navigation
- Back to AsyncMDSL language reference.
- Quick reference, tutorial, tools page
- Language specification:
- Service endpoint contract types and data contracts (schemas).
- Bindings and instance-level concepts.
- Back to MDSL homepage.
Copyright: See license information.