Skip to content

Commit f35fc99

Browse files
author
Tihomir Surdilovic
authored
Adding RPC for function defs (gRPC) (#246)
* Adding RPC for function defs (gRPC) Signed-off-by: Tihomir Surdilovic <[email protected]> * small typo Signed-off-by: Tihomir Surdilovic <[email protected]> * updating roadmap Signed-off-by: Tihomir Surdilovic <[email protected]> * update roadmap Signed-off-by: Tihomir Surdilovic <[email protected]> * small typo fix Signed-off-by: Tihomir Surdilovic <[email protected]>
1 parent e44691d commit f35fc99

File tree

3 files changed

+80
-22
lines changed

3 files changed

+80
-22
lines changed

roadmap/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ _Status description:_
3232
| ✔️| Adding comparison examples with Cadence | [comparison doc](../comparisons/README.md) |
3333
| ✔️| Adding workflow execTimeout and keepActive properties | [spec doc](../specification.md) |
3434
| ✔️| Adding SubFlow state repeat (loop) ability | [spec doc](../specification.md) |
35-
| ✔️| Adding comparison examples with BPMN | [comparison doc](../comparisons/README.md) |
35+
| ✔️| Adding comparison examples with BPMN | [comparison doc](../comparisons/README.md) |=
36+
| ✔️| Adding RPC type to function definitions (gRPC) | [spec doc](../specification.md) |
3637
| 🚩 | JSONPatch transformations | [issue](https://github.com/serverlessworkflow/specification/issues/149) |
3738
| 🚩 | Workflow invocation bindings | |
3839
| 🚩 | CE Subscriptions & Discovery | |
3940
| 🚩 | Error types | [issue](https://github.com/serverlessworkflow/specification/issues/200) |
4041
| 🚩 | Uniqueness constraint for workflows | [issue](https://github.com/serverlessworkflow/specification/issues/146) |
41-
| 🚩 | Function invocations (GRPC) | |
4242
| 🚩 | OpenAPI endpoint selection | |
4343
| 🚩 | Data triggers | |
4444
| 🚩 | JSON schema checks | |

schema/functions.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,15 @@
3535
},
3636
"operation": {
3737
"type": "string",
38-
"description": "If type `rest`, combination of the function/service OpenAPI definition URI and the operationID of the operation that needs to be invoked, separated by a '#'. If type is `expression` defines the workflow expression.",
38+
"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 `expression`, defines the workflow expression.",
3939
"minLength": 1
4040
},
4141
"type": {
4242
"type": "string",
43-
"description": "Defines the function type. Is either `rest` or `expression`. Default is `rest`",
43+
"description": "Defines the function type. Is either `rest`, `rpc` or `expression`. Default is `rest`",
4444
"enum": [
4545
"rest",
46+
"rpc",
4647
"expression"
4748
],
4849
"default": "rest"

specification.md

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ For more information on the history, development and design rationale behind the
7575
<img src="media/spec/spec-parts.png" width="600" alt="Serverless Workflow Specification Focus On Standards"/>
7676
</p>
7777

78-
Serverless Workflow language takes advantage of well-established and known standards such as [CloudEvents](https://cloudevents.io/) and [OpenApi](https://www.openapis.org/) specifications.
78+
Serverless Workflow language takes advantage of well-established and known standards such as [CloudEvents](https://cloudevents.io/), [OpenApi](https://www.openapis.org/) specifications,
79+
and [gRPC](https://grpc.io/).
7980

8081
## Project Components
8182

@@ -172,6 +173,7 @@ They can be referenced by their domain-specific names inside workflow [states](#
172173

173174
Reference the following sections to learn more about workflow functions:
174175
* [Using functions for RESTful service invocations](#Using-Functions-For-RESTful-Service-Invocations)
176+
* [Using functions for RPC service invocation](#Using-Functions-For-RPC-Service-Invocations)
175177
* [Using functions for expression evaluations](#Using-Functions-For-Expression-Evaluation)
176178

177179
### Using Functions For RESTful Service Invocations
@@ -186,22 +188,17 @@ To learn more about that, please reference the [event definitions](#Event-Defini
186188
as well as the [actions definitions](#Action-Definition) [eventRef](#EventRef-Definition) property.
187189

188190
Because of an overall lack of a common way to describe different services and their operations,
189-
workflow markups typically chose to define custom function definitions.
190-
This approach often runs into issues such as lack of markup portability, limited capabilities, as well as
191-
forces non-workflow-specific information such as service authentication to be added inside workflow markup.
191+
many workflow languages typically chose to define custom function definitions.
192+
This approach however often runs into issues such as lack of portability, limited capabilities, as well as
193+
forcing non-workflow-specific information, such as service authentication, to be added inside the workflow language.
192194

193195
To avoid these issues, the Serverless Workflow specification mandates that details about
194196
RESTful services and their operations be described using the [OpenAPI Specification](https://www.openapis.org/) specification.
195197
OpenAPI is a language-agnostic standard that describes discovery of RESTful services.
196198
This allows Serverless Workflow language to describe RESTful services in a portable
197199
way, as well as workflow runtimes to utilize OpenAPI tooling and APIs to invoke service operations.
198200

199-
The workflow markup allows defining non-restful services and their operations using the `metadata` property
200-
of [functions definitions](#Function-Definition). Note that using the function definitions `metadata` to add proprietary
201-
information about service execution can break the portability of the workflow language, meaning your
202-
workflow model may not be executable on different platforms that do not understand it.
203-
204-
Here is an example function definition for a service operation.
201+
Here is an example function definition for a RESTful service operation.
205202

206203
```json
207204
{
@@ -234,14 +231,74 @@ For example:
234231
```
235232

236233
Note that the referenced function definition type in this case must be `rest` (default type).
237-
If the referenced function definition type is `expression`, this should be regarded as
238-
an error during parsing of the workflow definition.
234+
235+
For more information about functions, reference the [Functions definitions](#Function-Definition) section.
236+
237+
### Using Functions For RPC Service Invocations
238+
239+
Similar to defining invocations of operations on RESTful services, you can also use the workflow
240+
[functions definitions](#Function-Definition) that follow the remote procedure call (RPC) protocol.
241+
For RPC invocations, the Serverless Workflow specification mandates that they are described using [gRPC](https://grpc.io/),
242+
a widely used RPC system.
243+
gRPC uses [Protocol Buffers](https://developers.google.com/protocol-buffers/docs/overview) to define messages, services,
244+
and the methods on those services that can be invoked.
245+
246+
Let's look at an example of invoking a service method using RPC. For this example let's say we have the following
247+
gRP prototocol buffer definition in a myuserservice.proto file:
248+
249+
```text
250+
service UserService {
251+
rpc AddUser(User) returns (google.protobuf.Empty) {
252+
option (google.api.http) = {
253+
post: "/api/v1/users"
254+
body: "*"
255+
};
256+
}
257+
rpc ListUsers(ListUsersRequest) returns (stream User) {
258+
option (google.api.http) = {
259+
get: "/api/v1/users"
260+
};
261+
}
262+
rpc ListUsersByRole(UserRole) returns (stream User) {
263+
option (google.api.http) = {
264+
get: "/api/v1/users/role"
265+
};
266+
}
267+
rpc UpdateUser(UpdateUserRequest) returns (User) {
268+
option (google.api.http) = {
269+
patch: "/api/v1/users/{user.id}"
270+
body: "*"
271+
};
272+
}
273+
}
274+
```
275+
276+
In our workflow definition, we can then use function definitions:
277+
278+
```json
279+
{
280+
"functions": [
281+
{
282+
"name": "listUsers",
283+
"operation": "file://myuserservice.proto#UserService#ListUsers",
284+
"type": "rpc"
285+
}
286+
]
287+
}
288+
```
289+
290+
Note that the `operation` property has the following format:
291+
```text
292+
<URI_to_proto_file>#<Service_Name>#<Service_Method_Name>
293+
```
294+
295+
Note that the referenced function definition type in this case must be `rpc`.
239296

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

242299
### Using Functions For Expression Evaluation
243300

244-
In addition to defining RESTful service operations, workflow [functions definitions](#Function-Definition)
301+
In addition to defining RESTful and RPC services and their operations, workflow [functions definitions](#Function-Definition)
245302
can also be used to define expressions that should be evaluated during workflow execution.
246303

247304
Defining expressions as part of function definitions has the benefit of being able to reference
@@ -303,9 +360,7 @@ Our expression function definitions can now be referenced by workflow states whe
303360
}
304361
```
305362

306-
Note that the used function definition type in this case must be `expression` .
307-
If the referenced function definition type is `rest` (default), this should be regarded as
308-
an error during parsing of the workflow definition.
363+
Note that the used function definition type in this case must be `expression`.
309364

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

@@ -695,8 +750,8 @@ not obeyed in the workflow definition.
695750
| Parameter | Description | Type | Required |
696751
| --- | --- | --- | --- |
697752
| name | Unique function name | string | yes |
698-
| operation | If type `rest`, combination of the function/service OpenAPI definition URI and the operationID of the operation that needs to be invoked, separated by a '#'. If type is `expression` defines the workflow expression. | string | no |
699-
| type | Defines the function type. Is either `rest` or `expression`. Default is `rest` | enum | no |
753+
| 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 `expression`, defines the workflow expression. | string | no |
754+
| type | Defines the function type. Is either `rest`, `rpc` or `expression`. Default is `rest` | enum | no |
700755
| [metadata](#Workflow-Metadata) | Metadata information. Can be used to define custom function information | object | no |
701756

702757
<details><summary><strong>Click to view example definition</strong></summary>
@@ -738,6 +793,8 @@ The `type` property defines the function type. Its value can be either `rest` or
738793
Depending on the function `type`, the `operation` property can be:
739794
* 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 '#'.
740795
For example `https://petstore.swagger.io/v2/swagger.json#getPetById`.
796+
* 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 '#'.
797+
For example `file://myuserservice.proto#UserService#ListUsers`.
741798
* If `type` is `expression`, defines the expression syntax. Take a look at the [workflow expressions section](#Workflow-Expressions) for more information on this.
742799

743800
The [`metadata`](#Workflow-Metadata) property allows users to define custom information to function definitions.

0 commit comments

Comments
 (0)