Skip to content

Commit 9c5cb54

Browse files
committed
Old Approach of HTTP operation
Signed-off-by: Ricardo Zanini <[email protected]>
1 parent b342026 commit 9c5cb54

File tree

3 files changed

+185
-13
lines changed

3 files changed

+185
-13
lines changed

roadmap/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ _Status description:_
3535
| ✔️| Apply fixes to auth spec schema [workflow schema](https://github.com/serverlessworkflow/specification/tree/main/schema) |
3636
| ✔️| Update the `dataInputSchema` top-level property by supporting the assignment of a JSON schema object [workflow schema](https://github.com/serverlessworkflow/specification/tree/main/specification.md#workflow-definition-structure) |
3737
| ✔️| Add the new `WORKFLOW` reserved keyword to workflow expressions |
38+
| ✔️| Add the new `http` function type [spec doc](https://github.com/serverlessworkflow/specification/tree/main/specification.md#using-functions-for-http-service-invocations) |
3839
| ✏️️| Add inline state defs in branches | |
39-
| ✏️️| Update rest function definition | |
4040
| ✏️️| Add "completedBy" functionality | |
4141
| ✏️️| Define workflow context | |
4242
| ✏️️| Start work on TCK | |

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 `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.",
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. If type is `http`, <HTTP_method>#<request_target>",
4040
"minLength": 1
4141
},
4242
"type": {
4343
"type": "string",
44-
"description": "Defines the function type. Is either `rest`, `asyncapi, `rpc`, `graphql`, `odata`, `expression`, or `custom`. Default is `rest`",
44+
"description": "Defines the function type. Is either `rest`, `http`,`asyncapi, `rpc`, `graphql`, `odata`, `expression`, or `custom`. Default is `rest`",
4545
"enum": [
4646
"rest",
47+
"http",
4748
"asyncapi",
4849
"rpc",
4950
"graphql",

specification.md

Lines changed: 181 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@
2323
+ [Using multiple data filters](#using-multiple-data-filters)
2424
+ [Data Merging](#data-merging)
2525
* [Workflow Functions](#workflow-functions)
26-
+ [Using Functions for RESTful Service Invocations](#using-functions-for-restful-service-invocations)
26+
+ [Using Functions for OpenAPI RESTFul Service Invocations](#using-functions-for-openapi-restful-service-invocations)
27+
+ [Using Functions for HTTP Service Invocations](#using-functions-for-http-service-invocations)
2728
+ [Using Functions for Async API Service Invocations](#using-functions-for-async-api-service-invocations)
28-
+ [Using Functions for RPC Service Invocations](#using-functions-for-rpc-service-invocations)
29+
+ [Using Functions for gRPC Service Invocations](#using-functions-for-grpc-service-invocations)
2930
+ [Using Functions for GraphQL Service Invocations](#using-functions-for-graphql-service-invocations)
3031
- [Invoking a GraphQL `Query`](#invoking-a-graphql-query)
3132
- [Invoking a GraphQL `Mutation`](#invoking-a-graphql-mutation)
@@ -991,8 +992,9 @@ They can be referenced by their domain-specific names inside workflow [states](#
991992

992993
Reference the following sections to learn more about workflow functions:
993994

994-
* [Using functions for RESTful service invocations](#Using-Functions-for-RESTful-Service-Invocations)
995-
* [Using Functions for Async API Service Invocations](#Using-Functions-for-Async-API-Service-Invocations)
995+
* [Using functions for OpenAPI RESTful service invocations](#using-functions-for-openapi-restful-service-invocations)
996+
+ [Using functions for HTTP Service Invocations](#using-functions-for-http-service-invocations)
997+
* [Using functions for Async API Service Invocations](#Using-Functions-for-Async-API-Service-Invocations)
996998
* [Using functions for gRPC service invocation](#Using-Functions-For-RPC-Service-Invocations)
997999
* [Using functions for GraphQL service invocation](#Using-Functions-For-GraphQL-Service-Invocations)
9981000
* [Using Functions for OData Service Invocations](#Using-Functions-for-OData-Service-Invocations)
@@ -1002,7 +1004,7 @@ Reference the following sections to learn more about workflow functions:
10021004
We can define if functions are invoked sync or async. Reference
10031005
the [functionRef](#FunctionRef-Definition) to learn more on how to do this.
10041006

1005-
#### Using Functions for RESTful Service Invocations
1007+
#### Using Functions for OpenAPI RESTful Service Invocations
10061008

10071009
[Functions](#Function-Definition) can be used to describe services and their operations that need to be invoked during
10081010
workflow execution. They can be referenced by states [action definitions](#Action-Definition) to clearly
@@ -1059,6 +1061,162 @@ Note that the referenced function definition type in this case must be `rest` (d
10591061

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

1064+
#### Using functions for HTTP Service Invocations
1065+
1066+
The specification supports describing HTTP invocations via a simplified interface in the [functions definition](#Function-Definition).
1067+
1068+
Here is an example function definition for HTTP requests with method `GET` and request target corresponding with [URI Template](https://www.rfc-editor.org/rfc/rfc6570.html) `/users/{id}`:
1069+
1070+
```json
1071+
{
1072+
"functions":[
1073+
{
1074+
"name":"queryUserById",
1075+
"operation":"GET#/users/{id}",
1076+
"type":"http"
1077+
}
1078+
]
1079+
}
1080+
```
1081+
1082+
Note that the [Function Definition](#Function-Definition)'s `operation` property must have the following format:
1083+
1084+
```text
1085+
<HTTP_method>#<request_target>
1086+
```
1087+
1088+
* The HTTP method used by the HTTP invocation. Can be any [valid HTTP method](https://www.rfc-editor.org/rfc/rfc9110.html#name-method-definitions) such as `GET`, `POST`, `PUT`, etc.
1089+
* The endpoint **location path** or the service full URL. Runtimes implementations are **discouraged** to expect the full URL in this field since this is a matter of infrastructure configuration.
1090+
1091+
The list below describes the HTTP function parameters in the `operation` attribute:
1092+
1093+
* Path parameters must be enclosed with braces (`{}`) as defined by [URI Templates](https://www.rfc-editor.org/rfc/rfc6570.html). The parameter name can be later referenced by the workflow states. For example: `/user/{id}`
1094+
* [Query parameters](https://www.rfc-editor.org/rfc/rfc9110.html#section-4.2.2) must be enclosed with braces (`{}`) as defined by [URI Templates](https://www.rfc-editor.org/rfc/rfc6570.html). The parameter name can be later referenced by the workflow states. For example: `/user?status={status}`.
1095+
1096+
<!-- TODO: refine how we are going to describe http headers parameters -->
1097+
Additional HTTP header fields can be passed via the `metadata` function definition. For example:
1098+
1099+
```json
1100+
{
1101+
"functions":[
1102+
{
1103+
"name":"queryUserById",
1104+
"operation":"GET#/users/{id}",
1105+
"type":"http",
1106+
"metadata":{
1107+
"x-custom-header":"the-value"
1108+
}
1109+
}
1110+
]
1111+
}
1112+
```
1113+
1114+
> Since the data manipulated in the Serverless Workflow specification is primarly JSON, runtimes are encouraged to support at least `Content-Type: application/json` header field for HTTP requests.
1115+
1116+
Avoid passing sensitive information in headers such as authentication tokens. See the [auth definition](#auth-definition) for more information.
1117+
1118+
HTTP request content doesn't need to be described in the function definition. **All the data within the state** should be passed to the HTTP request. See the [action data filter](#action-data-filters) if you need to limit the amount of data passed to a given action.
1119+
1120+
The function can be referenced during workflow execution when the invocation of the HTTP service is desired. For example:
1121+
1122+
```json
1123+
{
1124+
"states":[
1125+
{
1126+
"name":"QueryUserInfo",
1127+
"type":"operation",
1128+
"actions":[
1129+
{
1130+
"functionRef":"queryUserById",
1131+
"arguments":{
1132+
"id":"${ .user.id }"
1133+
}
1134+
}
1135+
],
1136+
"end":true
1137+
}
1138+
]
1139+
}
1140+
```
1141+
1142+
Example of the `POST` request sending the state data as part of the body:
1143+
1144+
```json
1145+
{
1146+
"functions":[
1147+
{
1148+
"name":"createUser",
1149+
"operation":"POST#/users",
1150+
"type":"http"
1151+
}
1152+
]
1153+
}
1154+
```
1155+
1156+
Then you can reference the `createUser` function and filter the input data to invoke it.
1157+
1158+
Input data example:
1159+
1160+
```json
1161+
{
1162+
"order":{
1163+
"id":"1234N",
1164+
"products":[
1165+
{
1166+
"name":"Product 1"
1167+
}
1168+
]
1169+
},
1170+
"user":{
1171+
"name":"John Doe",
1172+
1173+
}
1174+
}
1175+
```
1176+
1177+
Function invocation example:
1178+
1179+
```json
1180+
{
1181+
"states":[
1182+
{
1183+
"name":"CreateNewUser",
1184+
"type":"operation",
1185+
"actions":[
1186+
{
1187+
"functionRef":"createUser",
1188+
"actionDataFilter":{
1189+
"fromStateData":"${ .user }",
1190+
"toStateData":"${ .user.id }"
1191+
}
1192+
}
1193+
],
1194+
"end":true
1195+
}
1196+
]
1197+
}
1198+
```
1199+
1200+
In this case, only the contents of the `user` attribute will be passed to the function. The user ID returned by the HTTP request body will then be added to the state data:
1201+
1202+
```json
1203+
{
1204+
"order":{
1205+
"id":"1234N",
1206+
"products":[
1207+
{
1208+
"name":"Product 1"
1209+
}
1210+
]
1211+
},
1212+
"user":{
1213+
"id":"5678U",
1214+
"name":"John Doe",
1215+
1216+
}
1217+
}
1218+
```
1219+
10621220
#### Using Functions for Async API Service Invocations
10631221

10641222
[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).
@@ -1148,7 +1306,7 @@ Our defined function definition can then we referenced in a workflow [action](#A
11481306
}
11491307
```
11501308

1151-
#### Using Functions for RPC Service Invocations
1309+
#### Using Functions for gRPC Service Invocations
11521310

11531311
Similar to defining invocations of operations on RESTful services, you can also use the workflow
11541312
[functions definitions](#Function-Definition) that follow the remote procedure call (RPC) protocol.
@@ -1157,7 +1315,7 @@ a widely used RPC system.
11571315
gRPC uses [Protocol Buffers](https://developers.google.com/protocol-buffers/docs/overview) to define messages, services,
11581316
and the methods on those services that can be invoked.
11591317

1160-
Let's look at an example of invoking a service method using RPC. For this example let's say we have the following
1318+
Let's look at an example of invoking a service method using gRPC. For this example let's say we have the following
11611319
gRPC protocol buffer definition in a myuserservice.proto file:
11621320

11631321
```text
@@ -1409,7 +1567,7 @@ should follow the Serverless Workflow [OData Json schema](https://github.com/ser
14091567

14101568
#### Using Functions for Expression Evaluation
14111569

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

14151573
Defining expressions as part of function definitions has the benefit of being able to reference
@@ -3189,11 +3347,24 @@ Note that `transition` and `end` properties are mutually exclusive, meaning that
31893347
| Parameter | Description | Type | Required |
31903348
| --- | --- | --- | --- |
31913349
| name | Unique function name | string | yes |
3192-
| 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 | yes |
3193-
| type | Defines the function type. Can be either `rest`, `asyncapi`, `rpc`, `graphql`, `odata`, `expression`, or [`custom`](#defining-custom-function-types). Default is `rest` | enum | no |
3350+
| operation | See the table "Function Operation description by type" below. | string | yes |
3351+
| type | Defines the function type. Can be either `rest`, `http`, `asyncapi`, `rpc`, `graphql`, `odata`, `expression`, or [`custom`](#defining-custom-function-types). Default is `rest` | enum | no |
31943352
| authRef | References an [auth definition](#Auth-Definition) name to be used to access to resource defined in the operation parameter | string | no |
31953353
| [metadata](#Workflow-Metadata) | Metadata information. Can be used to define custom function information | object | no |
31963354

3355+
Function Operation description by type:
3356+
3357+
| Type | Operation Description |
3358+
| ---- | --------- |
3359+
| `rest` | <path_to_openapi_definition>#<operation_id> |
3360+
| `http` | <HTTP_method>#<request_target> |
3361+
| `asyncapi` | <path_to_asyncapi_definition>#<operation_id> |
3362+
| `rpc` | <path_to_grpc_proto_file>#<service_name>#<service_method> |
3363+
| `graphql` | <url_to_graphql_endpoint>#<literal \"mutation\" or \"query\">#<query_or_mutation_name> |
3364+
| `odata` | <URI_to_odata_service>#<Entity_Set_Name> |
3365+
| `expression` | defines the workflow expression |
3366+
| `custom` | see [Defining custom function types](#defining-custom-function-types)
3367+
31973368
<details><summary><strong>Click to view example definition</strong></summary>
31983369
<p>
31993370

0 commit comments

Comments
 (0)