Skip to content

Commit 90bc805

Browse files
committed
Fix #818 - Merge REST and OPENAPI operations, introduce HTTP functions
Signed-off-by: Ricardo Zanini <[email protected]>
1 parent b3422f4 commit 90bc805

File tree

3 files changed

+192
-24
lines changed

3 files changed

+192
-24
lines changed

examples/curl.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"id": "curl",
3+
"version": "1.0.0",
4+
"specVersion": "0.9",
5+
"name": "curl-workflow",
6+
"description": "Curl Google",
7+
"start": "curl",
8+
"functions": [
9+
{
10+
"name": "curl-google",
11+
"type": "http",
12+
"operation": {
13+
"method": "GET",
14+
"uri": "https://www.google.com/search?q={query}"
15+
}
16+
}
17+
],
18+
"states": [
19+
{
20+
"name": "curl",
21+
"type": "operation",
22+
"actions": [
23+
{
24+
"name": "do-curl",
25+
"functionRef": {
26+
"refName": "curl-google",
27+
"arguments": {
28+
"query": "${ .query }"
29+
}
30+
}
31+
}
32+
],
33+
"end": true
34+
}
35+
]
36+
}

schema/functions.json

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@
2222
}
2323
]
2424
},
25-
"required": [
26-
"functions"
27-
],
25+
"required": ["functions"],
2826
"definitions": {
2927
"function": {
3028
"type": "object",
@@ -40,9 +38,9 @@
4038
},
4139
"type": {
4240
"type": "string",
43-
"description": "Defines the function type. Is either `rest`, `openapi`,`asyncapi, `rpc`, `graphql`, `odata`, `expression`, or `custom`. Default is `openapi`.",
41+
"description": "Defines the function type. Is either `http`, `openapi`,`asyncapi, `rpc`, `graphql`, `odata`, `expression`, or `custom`. Default is `openapi`.",
4442
"enum": [
45-
"rest",
43+
"http",
4644
"openapi",
4745
"asyncapi",
4846
"rpc",
@@ -77,9 +75,7 @@
7775
}
7876
},
7977
"additionalProperties": false,
80-
"required": [
81-
"resource"
82-
]
78+
"required": ["resource"]
8379
}
8480
]
8581
},
@@ -88,10 +84,7 @@
8884
}
8985
},
9086
"additionalProperties": false,
91-
"required": [
92-
"name",
93-
"operation"
94-
]
87+
"required": ["name", "operation"]
9588
},
9689
"operation": {
9790
"oneOf": [
@@ -109,8 +102,39 @@
109102
"type": "object"
110103
}
111104
}
105+
},
106+
{
107+
"type": "object",
108+
"description": "HTTP Function operation definition",
109+
"properties": {
110+
"method": {
111+
"enum": [
112+
"GET",
113+
"HEAD",
114+
"POST",
115+
"PUT",
116+
"DELETE",
117+
"CONNECT",
118+
"OPTIONS",
119+
"TRACE"
120+
],
121+
"default": "GET"
122+
},
123+
"uri": {
124+
"type": "string"
125+
},
126+
"headers": {
127+
"type": "object",
128+
"additionalProperties": { "type": "string" }
129+
},
130+
"cookies": {
131+
"type": "object",
132+
"additionalProperties": { "type": "string" }
133+
}
134+
},
135+
"required": ["method", "uri"]
112136
}
113137
]
114138
}
115139
}
116-
}
140+
}

specification.md

Lines changed: 119 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
+ [Data Merging](#data-merging)
2525
* [Workflow Functions](#workflow-functions)
2626
+ [Using Functions for OpenAPI Service Invocations](#using-functions-for-openapi-service-invocations)
27-
+ [Using Functions for RESTful Service Invocations](#using-functions-for-restful-service-invocations)
27+
+ [Using Functions for HTTP Service Invocations](#using-functions-for-http-service-invocations)
2828
+ [Using Functions for Async API Service Invocations](#using-functions-for-async-api-service-invocations)
2929
+ [Using Functions for RPC Service Invocations](#using-functions-for-rpc-service-invocations)
3030
+ [Using Functions for GraphQL Service Invocations](#using-functions-for-graphql-service-invocations)
@@ -995,7 +995,7 @@ They can be referenced by their domain-specific names inside workflow [states](#
995995
Reference the following sections to learn more about workflow functions:
996996

997997
* [Using functions for OpenAPI Service invocations](#using-functions-for-openapi-service-invocations)
998-
+ [Using functions for RESTful Service Invocations](#using-functions-for-rest-service-invocations)
998+
+ [Using functions for HTTP Service Invocations](#using-functions-for-http-service-invocations)
999999
* [Using functions for Async API Service Invocations](#Using-Functions-for-Async-API-Service-Invocations)
10001000
* [Using functions for gRPC service invocation](#Using-Functions-For-RPC-Service-Invocations)
10011001
* [Using functions for GraphQL service invocation](#Using-Functions-For-GraphQL-Service-Invocations)
@@ -1061,11 +1061,7 @@ For example:
10611061

10621062
Note that the referenced function definition type in this case must be `openapi` (default type).
10631063

1064-
For more information about functions, reference the [Functions definitions](#Function-Definition) section.
1065-
1066-
#### Using functions for RESTful Service Invocations
1067-
1068-
The specification also supports describing REST invocations in the [functions definition](#Function-Definition) using [OpenAPI Paths Object](https://spec.openapis.org/oas/v3.1.0#paths-object).
1064+
The specification also supports describing OpenAPI for REST invocations inline in the [functions definition](#Function-Definition) using [OpenAPI Paths Object](https://spec.openapis.org/oas/v3.1.0#paths-object).
10691065

10701066
Here is an example function definition for REST requests with method `GET` and request target corresponding with [URI Template](https://www.rfc-editor.org/rfc/rfc6570.html) `/users/{id}`:
10711067

@@ -1085,7 +1081,7 @@ Here is an example function definition for REST requests with method `GET` and r
10851081
}
10861082
}
10871083
},
1088-
"type":"rest"
1084+
"type":"openapi"
10891085
}
10901086
]
10911087
}
@@ -1122,7 +1118,7 @@ Example of the `POST` request sending the state data as part of the body:
11221118
"functions":[
11231119
{
11241120
"name": "createUser",
1125-
"type": "rest",
1121+
"type": "openapi",
11261122
"operation": {
11271123
"/users": {
11281124
"post": {
@@ -1219,7 +1215,119 @@ In this case, only the contents of the `user` attribute will be passed to the fu
12191215
}
12201216
```
12211217

1222-
The specification does not support the [Security Requirement Object](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) since its redundat to function [Auth Definition](#Auth-Definition). If provided, this field is ignored.
1218+
When inlining the OpenAPI operation, the specification does not support the [Security Requirement Object](https://spec.openapis.org/oas/v3.1.0#security-requirement-object) since its redundat to function [Auth Definition](#Auth-Definition). If provided, this field is ignored.
1219+
1220+
For more information about functions, reference the [Functions definitions](#Function-Definition) section.
1221+
1222+
#### Using functions for HTTP Service Invocations
1223+
1224+
The HTTP function can make HTTP requests to a given endpoint. It can be used in cases a service doesn't have an OpenAPI definition or users require a simple HTTP, curl-style invocation.
1225+
1226+
The table below lists the `operation` properties for the `http` function type.
1227+
1228+
| Property | Description | Type | Required |
1229+
| --- | --- | --- | --- |
1230+
1231+
| uri | The URI where to send the request | String | yes |
1232+
| method | The HTTP method according to the [RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616#page-36) | String | yes |
1233+
| headers | Headers to send in the HTTP call. The `Content-Type` header mandates the body convertion. | Map | no |
1234+
| cookies | Cookies to send in the HTTP call. | Map | no |
1235+
1236+
Note that in the function definition, these values are static. When invoking the function in the `actions` definition, `jq` can be used to set the attribute values.
1237+
1238+
Here is a function definition example for a HTTP service operation.
1239+
1240+
```json
1241+
{
1242+
"functions": [
1243+
{
1244+
"name": "getPetById",
1245+
"type": "http",
1246+
"operation": {
1247+
"method": "GET",
1248+
"uri": "https://petstore.swagger.io/v2/pet/{petId}"
1249+
}
1250+
}
1251+
]
1252+
}
1253+
```
1254+
1255+
This function can be used later in the workflow definition:
1256+
1257+
```json
1258+
{
1259+
"states":[
1260+
{
1261+
"name": "getpet",
1262+
"type": "operation",
1263+
"actions":[
1264+
{
1265+
"functionRef": "getPetById",
1266+
"arguments":{
1267+
"petId": "${ .pet.id }"
1268+
}
1269+
}
1270+
],
1271+
"end":true
1272+
}
1273+
]
1274+
}
1275+
```
1276+
1277+
Not that the `arguments` attribute must map the template in the `uri` definition so the underlying engine can map the arguments correctly.
1278+
1279+
The `arguments` attribute accepts the following reserved properties when calling a HTTP function type:
1280+
1281+
| Property | Description | Type | Required |
1282+
| --- | --- | --- | --- |
1283+
1284+
| body | The HTTP body. If an object, it will be sent as a JSON payload by default if the `Content-Type` header is missing. Otherwise, it will try to convert it based on the `Content-Type` header definition | Object or String | no |
1285+
| headers | Headers to send in the HTTP call. The `Content-Type` header mandates the body convertion. | Map | no |
1286+
| cookies | Cookies to send in the HTTP call. | Map | no |
1287+
1288+
These attributes are merged with the ones in the function definition.
1289+
1290+
The listing below exemplifies how to define and call a HTTP POST endpoint.
1291+
1292+
```json
1293+
{
1294+
"functions": [
1295+
{
1296+
"name": "createPet",
1297+
"type": "http",
1298+
"operation": {
1299+
"method": "POST",
1300+
"uri": "https://petstore.swagger.io/v2/pet/",
1301+
"headers": {
1302+
"Content-Type": "application/json"
1303+
}
1304+
}
1305+
}
1306+
]
1307+
},
1308+
{
1309+
"states":[
1310+
{
1311+
"name":"create-pet",
1312+
"type":"operation",
1313+
"actions":[
1314+
{
1315+
"functionRef":"createPet",
1316+
"arguments":{
1317+
"body": {
1318+
"name": "Lulu"
1319+
},
1320+
"headers": {
1321+
"my-header": "my-value"
1322+
}
1323+
}
1324+
}
1325+
],
1326+
"end":true
1327+
}
1328+
]
1329+
}
1330+
```
12231331

12241332
#### Using Functions for Async API Service Invocations
12251333

@@ -3294,7 +3402,7 @@ Note that `transition` and `end` properties are mutually exclusive, meaning that
32943402
| --- | --- | --- | --- |
32953403
| name | Unique function name. Must follow the [Serverless Workflow Naming Convention](#naming-convention) | string | yes |
32963404
| operation | See the table "Function Operation description by type" below. | string or object | yes |
3297-
| type | Defines the function type. Can be either `rest`, `openapi`, `asyncapi`, `rpc`, `graphql`, `odata`, `expression`, or [`custom`](#defining-custom-function-types). Default is `openapi` | enum | no |
3405+
| type | Defines the function type. Can be either `http`, `openapi`, `asyncapi`, `rpc`, `graphql`, `odata`, `expression`, or [`custom`](#defining-custom-function-types). Default is `openapi` | enum | no |
32983406
| authRef | References an [auth definition](#Auth-Definition) name to be used to access to resource defined in the operation parameter | string | no |
32993407
| [metadata](#Workflow-Metadata) | Metadata information. Can be used to define custom function information | object | no |
33003408

0 commit comments

Comments
 (0)