Skip to content

Commit 9452d9c

Browse files
authored
Adding AsyncApi support for function definitions (#434)
Signed-off-by: Tihomir Surdilovic <[email protected]>
1 parent f242616 commit 9452d9c

File tree

3 files changed

+98
-4
lines changed

3 files changed

+98
-4
lines changed

roadmap/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ _Status description:_
3939
| ✔️| Added State execution timeouts | [spec doc](../specification.md) |
4040
| ✔️| Temporarily removed `waitForCompletion` for subflows | [spec doc](../specification.md) |
4141
| ✔️| Added function definition support for OData | [spec doc](../specification.md) |
42+
| ✔️| Added function definition support for AsyncAPI | [spec doc](../specification.md) |
4243
| ✏️ | AsyncAPI operation support | |
4344
| ✏️ | OData function definition support | |
4445
| ✏️ | Update to retries - state specific rather than error specific | |

schema/functions.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@
3636
},
3737
"operation": {
3838
"type": "string",
39-
"description": "If type is `rest`, <path_to_openapi_definition>#<operation_id>. If type is `rpc`, <path_to_grpc_proto_file>#<service_name>#<service_method>. If type is `graphql`, <url_to_graphql_endpoint>#<literal \\\"mutation\\\" or \\\"query\\\">#<query_or_mutation_name>. If type is `odata`, <URI_to_odata_service>#<Entity_Set_Name>. If type is `expression`, defines the workflow expression.",
39+
"description": "If type is `rest`, <path_to_openapi_definition>#<operation_id>. If type is `asyncapi`, <path_to_asyncapi_definition>#<operation_id>. If type is `rpc`, <path_to_grpc_proto_file>#<service_name>#<service_method>. If type is `graphql`, <url_to_graphql_endpoint>#<literal \\\"mutation\\\" or \\\"query\\\">#<query_or_mutation_name>. If type is `odata`, <URI_to_odata_service>#<Entity_Set_Name>. If type is `expression`, defines the workflow expression.",
4040
"minLength": 1
4141
},
4242
"type": {
4343
"type": "string",
44-
"description": "Defines the function type. Is either `rest`, `rpc`, `graphql`, `odata`, or `expression`. Default is `rest`",
44+
"description": "Defines the function type. Is either `rest`, `asyncapi, `rpc`, `graphql`, `odata`, or `expression`. Default is `rest`",
4545
"enum": [
4646
"rest",
47+
"asyncapi",
4748
"rpc",
4849
"graphql",
4950
"odata",

specification.md

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
+ [Data Merging](#data-merging)
2525
* [Workflow Functions](#workflow-functions)
2626
+ [Using Functions for RESTful Service Invocations](#using-functions-for-restful-service-invocations)
27+
+ [Using Functions for Async API Invocations](#using-functions-for-async-api-invocations)
2728
+ [Using Functions for RPC Service Invocations](#using-functions-for-rpc-service-invocations)
2829
+ [Using Functions for GraphQL Service Invocations](#using-functions-for-graphql-service-invocations)
2930
- [Invoking a GraphQL `Query`](#invoking-a-graphql-query)
@@ -1089,6 +1090,95 @@ Note that the referenced function definition type in this case must be `rest` (d
10891090

10901091
For more information about functions, reference the [Functions definitions](#Function-Definition) section.
10911092

1093+
#### Using Functions for Async API Service Invocations
1094+
1095+
[Functions](#Function-Definition) can be used to invoke PUBLISH and SUBSCRIBE operations on a message broker documented by the [Async API Specification](https://www.asyncapi.com/docs/specifications/v2.1.0).
1096+
[Async API operations](https://www.asyncapi.com/docs/specifications/v2.1.0#operationObject) are bound to a [channel](https://www.asyncapi.com/docs/specifications/v2.1.0#definitionsChannel) which describes the technology, security mechanisms, input and validation to be used for their execution.
1097+
1098+
Let's take a look at a hypothetical Async API document (assumed its stored locally with the file name `streetlightsapi.yaml`) and define a single publish operation:
1099+
1100+
```yaml
1101+
asyncapi: 2.1.0
1102+
info:
1103+
title: Streetlights API
1104+
version: 1.0.0
1105+
description: |
1106+
The Smartylighting Streetlights API allows you
1107+
to remotely manage the city lights.
1108+
license:
1109+
name: Apache 2.0
1110+
url: https://www.apache.org/licenses/LICENSE-2.0
1111+
servers:
1112+
mosquitto:
1113+
url: mqtt://test.mosquitto.org
1114+
protocol: mqtt
1115+
channels:
1116+
light/measured:
1117+
publish:
1118+
summary: Inform about environmental lighting conditions for a particular streetlight.
1119+
operationId: onLightMeasured
1120+
message:
1121+
name: LightMeasured
1122+
payload:
1123+
type: object
1124+
properties:
1125+
id:
1126+
type: integer
1127+
minimum: 0
1128+
description: Id of the streetlight.
1129+
lumens:
1130+
type: integer
1131+
minimum: 0
1132+
description: Light intensity measured in lumens.
1133+
sentAt:
1134+
type: string
1135+
format: date-time
1136+
description: Date and time when the message was sent.
1137+
```
1138+
1139+
To define a workflow action invocation, we can then use the following workflow [Function Definition](#Function-Definition) and set the `operation` to `onLightMeasured`:
1140+
1141+
```json
1142+
{
1143+
"functions": [
1144+
{
1145+
"name": "publishLightMeasurements",
1146+
"operation": "file://streetlightsapi.yaml#onLightMeasured",
1147+
"type": "asyncapi"
1148+
}]
1149+
}
1150+
```
1151+
1152+
Note that the [Function Definition](#Function-Definition)'s `operation` property must have the following format:
1153+
1154+
```text
1155+
<URI_to_asyncapi_file>#<OperationId>
1156+
```
1157+
1158+
Also note that the referenced function definition type in this case must have the value `asyncapi`.
1159+
1160+
Our defined function definition can then we referenced in a workflow [action](#Action-Definition), for example:
1161+
1162+
```json
1163+
{
1164+
"name": "Publish Measurements",
1165+
"type": "operation",
1166+
"actions":[
1167+
{
1168+
"name": "Publish Light Measurements",
1169+
"functionRef":{
1170+
"refName": "publishLightMeasurements",
1171+
"arguments":{
1172+
"id": "${ .currentLight.id }",
1173+
"lumens": "${ .currentLight.lumens }",
1174+
"sentAt": "${ now }"
1175+
}
1176+
}
1177+
}
1178+
]
1179+
}
1180+
```
1181+
10921182
#### Using Functions for RPC Service Invocations
10931183

10941184
Similar to defining invocations of operations on RESTful services, you can also use the workflow
@@ -1350,7 +1440,7 @@ should follow the Serverless Workflow [OData Json schema](https://github.com/ser
13501440

13511441
#### Using Functions for Expression Evaluation
13521442

1353-
In addition to defining RESTful, RPC, GraphQL and OData services and their operations, workflow [functions definitions](#Function-Definition)
1443+
In addition to defining RESTful, AsyncAPI, RPC, GraphQL and OData services and their operations, workflow [functions definitions](#Function-Definition)
13541444
can also be used to define expressions that should be evaluated during workflow execution.
13551445

13561446
Defining expressions as part of function definitions has the benefit of being able to reference
@@ -3023,7 +3113,7 @@ section.
30233113
| Parameter | Description | Type | Required |
30243114
| --- | --- | --- | --- |
30253115
| name | Unique function name | string | yes |
3026-
| operation | If type is `rest`, <path_to_openapi_definition>#<operation_id>. If type is `rpc`, <path_to_grpc_proto_file>#<service_name>#<service_method>. If type is `graphql`, <url_to_graphql_endpoint>#<literal \"mutation\" or \"query\">#<query_or_mutation_name>. If type is `odata`, <URI_to_odata_service>#<Entity_Set_Name>. If type is `expression`, defines the workflow expression. | string | no |
3116+
| operation | If type is `rest`, <path_to_openapi_definition>#<operation_id>. If type is `asyncapi`, <path_to_asyncapi_definition>#<operation_id>. If type is `rpc`, <path_to_grpc_proto_file>#<service_name>#<service_method>. If type is `graphql`, <url_to_graphql_endpoint>#<literal \"mutation\" or \"query\">#<query_or_mutation_name>. If type is `odata`, <URI_to_odata_service>#<Entity_Set_Name>. If type is `expression`, defines the workflow expression. | string | no |
30273117
| type | Defines the function type. Is either `rest`, `rpc`, `odata` or `expression`. Default is `rest` | enum | no |
30283118
| authRef | References an [auth definition](#Auth-Definition) name to be used to access to resource defined in the operation parameter | string | no |
30293119
| [metadata](#Workflow-Metadata) | Metadata information. Can be used to define custom function information | object | no |
@@ -3068,6 +3158,8 @@ Depending on the function `type`, the `operation` property can be:
30683158

30693159
* If `type` is `rest`, a combination of the function/service OpenAPI definition document URI and the particular service operation that needs to be invoked, separated by a '#'.
30703160
For example `https://petstore.swagger.io/v2/swagger.json#getPetById`.
3161+
* If `type` is `asyncapi`, a combination of the AsyncApi definition document URI and the particular service operation that needs to be invoked, separated by a '#'.
3162+
For example `file://streetlightsapi.yaml#onLightMeasured`.
30713163
* If `type` is `rpc`, a combination of the gRPC proto document URI and the particular service name and service method name that needs to be invoked, separated by a '#'.
30723164
For example `file://myuserservice.proto#UserService#ListUsers`.
30733165
* If `type` is `graphql`, a combination of the GraphQL schema definition URI and the particular service name and service method name that needs to be invoked, separated by a '#'.

0 commit comments

Comments
 (0)