Skip to content

Commit 4efb488

Browse files
committed
Fix #818 - Merge REST and OPENAPI operations, introduce HTTP functions
Signed-off-by: Ricardo Zanini <zanini@redhat.com>
1 parent 9f79f8f commit 4efb488

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)
@@ -996,7 +996,7 @@ They can be referenced by their domain-specific names inside workflow [states](#
996996
Reference the following sections to learn more about workflow functions:
997997

998998
* [Using functions for OpenAPI Service invocations](#using-functions-for-openapi-service-invocations)
999-
+ [Using functions for RESTful Service Invocations](#using-functions-for-rest-service-invocations)
999+
+ [Using functions for HTTP Service Invocations](#using-functions-for-http-service-invocations)
10001000
* [Using functions for Async API Service Invocations](#Using-Functions-for-Async-API-Service-Invocations)
10011001
* [Using functions for gRPC service invocation](#Using-Functions-For-RPC-Service-Invocations)
10021002
* [Using functions for GraphQL service invocation](#Using-Functions-For-GraphQL-Service-Invocations)
@@ -1062,11 +1062,7 @@ For example:
10621062

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

1065-
For more information about functions, reference the [Functions definitions](#Function-Definition) section.
1066-
1067-
#### Using functions for RESTful Service Invocations
1068-
1069-
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).
1065+
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).
10701066

10711067
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}`:
10721068

@@ -1086,7 +1082,7 @@ Here is an example function definition for REST requests with method `GET` and r
10861082
}
10871083
}
10881084
},
1089-
"type":"rest"
1085+
"type":"openapi"
10901086
}
10911087
]
10921088
}
@@ -1123,7 +1119,7 @@ Example of the `POST` request sending the state data as part of the body:
11231119
"functions":[
11241120
{
11251121
"name": "createUser",
1126-
"type": "rest",
1122+
"type": "openapi",
11271123
"operation": {
11281124
"/users": {
11291125
"post": {
@@ -1220,7 +1216,119 @@ In this case, only the contents of the `user` attribute will be passed to the fu
12201216
}
12211217
```
12221218

1223-
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+
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.
1220+
1221+
For more information about functions, reference the [Functions definitions](#Function-Definition) section.
1222+
1223+
#### Using functions for HTTP Service Invocations
1224+
1225+
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.
1226+
1227+
The table below lists the `operation` properties for the `http` function type.
1228+
1229+
| Property | Description | Type | Required |
1230+
| --- | --- | --- | --- |
1231+
1232+
| uri | The URI where to send the request | String | yes |
1233+
| method | The HTTP method according to the [RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616#page-36) | String | yes |
1234+
| headers | Headers to send in the HTTP call. The `Content-Type` header mandates the body convertion. | Map | no |
1235+
| cookies | Cookies to send in the HTTP call. | Map | no |
1236+
1237+
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.
1238+
1239+
Here is a function definition example for a HTTP service operation.
1240+
1241+
```json
1242+
{
1243+
"functions": [
1244+
{
1245+
"name": "getPetById",
1246+
"type": "http",
1247+
"operation": {
1248+
"method": "GET",
1249+
"uri": "https://petstore.swagger.io/v2/pet/{petId}"
1250+
}
1251+
}
1252+
]
1253+
}
1254+
```
1255+
1256+
This function can be used later in the workflow definition:
1257+
1258+
```json
1259+
{
1260+
"states":[
1261+
{
1262+
"name": "getpet",
1263+
"type": "operation",
1264+
"actions":[
1265+
{
1266+
"functionRef": "getPetById",
1267+
"arguments":{
1268+
"petId": "${ .pet.id }"
1269+
}
1270+
}
1271+
],
1272+
"end":true
1273+
}
1274+
]
1275+
}
1276+
```
1277+
1278+
Not that the `arguments` attribute must map the template in the `uri` definition so the underlying engine can map the arguments correctly.
1279+
1280+
The `arguments` attribute accepts the following reserved properties when calling a HTTP function type:
1281+
1282+
| Property | Description | Type | Required |
1283+
| --- | --- | --- | --- |
1284+
1285+
| 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 |
1286+
| headers | Headers to send in the HTTP call. The `Content-Type` header mandates the body convertion. | Map | no |
1287+
| cookies | Cookies to send in the HTTP call. | Map | no |
1288+
1289+
These attributes are merged with the ones in the function definition.
1290+
1291+
The listing below exemplifies how to define and call a HTTP POST endpoint.
1292+
1293+
```json
1294+
{
1295+
"functions": [
1296+
{
1297+
"name": "createPet",
1298+
"type": "http",
1299+
"operation": {
1300+
"method": "POST",
1301+
"uri": "https://petstore.swagger.io/v2/pet/",
1302+
"headers": {
1303+
"Content-Type": "application/json"
1304+
}
1305+
}
1306+
}
1307+
]
1308+
},
1309+
{
1310+
"states":[
1311+
{
1312+
"name":"create-pet",
1313+
"type":"operation",
1314+
"actions":[
1315+
{
1316+
"functionRef":"createPet",
1317+
"arguments":{
1318+
"body": {
1319+
"name": "Lulu"
1320+
},
1321+
"headers": {
1322+
"my-header": "my-value"
1323+
}
1324+
}
1325+
}
1326+
],
1327+
"end":true
1328+
}
1329+
]
1330+
}
1331+
```
12241332

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

@@ -3359,7 +3467,7 @@ Note that `transition` and `end` properties are mutually exclusive, meaning that
33593467
| --- | --- | --- | --- |
33603468
| name | Unique function name. Must follow the [Serverless Workflow Naming Convention](#naming-convention) | string | yes |
33613469
| operation | See the table "Function Operation description by type" below. | string or object | yes |
3362-
| 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 |
3470+
| 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 |
33633471
| authRef | References an [auth definition](#Auth-Definition) name to be used to access to resource defined in the operation parameter | string | no |
33643472
| [metadata](#Workflow-Metadata) | Metadata information. Can be used to define custom function information | object | no |
33653473

0 commit comments

Comments
 (0)