-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gRPC and OpenAPI Integration #1201
Comments
Example for OpenAPIopenapi: '3.0.3'
info:
title: Todo REST API
version: '1.0.0'
description: A RESTful API for managing todo items
servers:
- url: /api/v1
description: Base API path
components:
schemas:
Todo:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
title:
type: string
minLength: 1
maxLength: 200
description:
type: string
maxLength: 2000
completed:
type: boolean
default: false
dueDate:
type: string
format: date-time
userId:
type: string
createdAt:
type: string
format: date-time
readOnly: true
updatedAt:
type: string
format: date-time
readOnly: true
required:
- id
- title
- completed
- userId
- createdAt
- updatedAt
TodoCreate:
type: object
properties:
title:
type: string
minLength: 1
maxLength: 200
description:
type: string
maxLength: 2000
dueDate:
type: string
format: date-time
userId:
type: string
required:
- title
- userId
TodoUpdate:
type: object
properties:
title:
type: string
minLength: 1
maxLength: 200
description:
type: string
maxLength: 2000
completed:
type: boolean
dueDate:
type: string
format: date-time
minProperties: 1
TodoList:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Todo'
metadata:
type: object
properties:
total:
type: integer
minimum: 0
limit:
type: integer
minimum: 1
offset:
type: integer
minimum: 0
required:
- total
- limit
- offset
required:
- data
- metadata
TodoResponse:
type: object
properties:
data:
$ref: '#/components/schemas/Todo'
required:
- data
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
enum:
- VALIDATION_ERROR
- UNAUTHORIZED
- FORBIDDEN
- NOT_FOUND
- RATE_LIMIT_EXCEEDED
- INTERNAL_ERROR
message:
type: string
details:
type: array
items:
type: object
properties:
field:
type: string
message:
type: string
required:
- field
- message
required:
- code
- message
parameters:
TodoId:
name: todoId
in: path
required: true
schema:
type: string
format: uuid
UserId:
name: userId
in: query
required: true
schema:
type: string
Status:
name: status
in: query
schema:
type: string
enum: [active, completed]
Limit:
name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 50
Offset:
name: offset
in: query
schema:
type: integer
minimum: 0
default: 0
SortBy:
name: sortBy
in: query
schema:
type: string
enum: [createdAt, dueDate]
default: createdAt
SortOrder:
name: sortOrder
in: query
schema:
type: string
enum: [asc, desc]
default: desc
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
paths:
/todos:
get:
summary: List todos
parameters:
- $ref: '#/components/parameters/UserId'
- $ref: '#/components/parameters/Status'
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/Offset'
- $ref: '#/components/parameters/SortBy'
- $ref: '#/components/parameters/SortOrder'
responses:
'200':
description: Successfully retrieved todos
headers:
ETag:
schema:
type: string
Last-Modified:
schema:
type: string
X-Request-ID:
schema:
type: string
X-RateLimit-Limit:
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
X-RateLimit-Reset:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/TodoList'
'400':
description: Invalid parameters
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Too many requests
headers:
Retry-After:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
summary: Create a new todo
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TodoCreate'
responses:
'201':
description: Todo created successfully
headers:
Location:
schema:
type: string
format: uri
ETag:
schema:
type: string
X-Request-ID:
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/TodoResponse'
'400':
description: Invalid input
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/todos/{todoId}:
parameters:
- $ref: '#/components/parameters/TodoId'
get:
summary: Get a specific todo
responses:
'200':
description: Successfully retrieved todo
headers:
ETag:
schema:
type: string
Last-Modified:
schema:
type: string
X-Request-ID:
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/TodoResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Todo not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
patch:
summary: Update a todo
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TodoUpdate'
responses:
'200':
description: Todo updated successfully
headers:
ETag:
schema:
type: string
X-Request-ID:
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/TodoResponse'
'400':
description: Invalid input
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Todo not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
delete:
summary: Delete a todo
responses:
'204':
description: Todo deleted successfully
headers:
X-Request-ID:
schema:
type: string
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Todo not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error' package api:todos@1.0.0;
// Common types used across the API
interface types {
// Authentication types derived from OpenAPI security schemes
record bearer-token {
token: string,
}
// Core resource type
record todo {
id: string,
title: string,
description: option<string>,
completed: bool,
due-date: option<string>,
user-id: string,
created-at: string,
updated-at: string,
}
variant error {
unauthorized,
not-found,
validation-error(list<string>),
rate-limited { retry-after: u32 },
server-error,
}
}
interface todos-collection {
use types.{todo, bearer-token, error};
// Request/response types with domain-appropriate fields
record list-request {
auth: bearer-token,
user-id: string,
status: option<string>,
limit: option<u32>,
%offset: option<u32>,
}
record list-response {
items: list<todo>,
total: u32,
limit: u32,
%offset: u32,
version: string, // From ETag
last-updated: option<string>, // From Last-Modified
}
record create-request {
auth: bearer-token,
title: string,
description: option<string>,
due-date: option<string>,
user-id: string,
}
// Note: Response includes versioning info directly in return type
list: func(request: list-request) -> result<list-response, error>;
create: func(request: create-request) -> result<todo, error>;
}
interface todos-resource {
use types.{todo, bearer-token, error};
record update-request {
auth: bearer-token,
title: option<string>,
description: option<string>,
completed: option<bool>,
due-date: option<string>,
expected-version: option<string>, // If-Match header
}
get: func(id: string, auth: bearer-token) -> result<todo, error>;
update: func(id: string, request: update-request) -> result<todo, error>;
delete: func(id: string, auth: bearer-token) -> result<unit, error>;
}
world todos-api {
export todos-collection;
export todos-resource;
} |
Example for gRPCsyntax = "proto3";
package core.todo.v1;
option go_package = "github.com/koblas/grpc-todo/protos";
message TodoListRequest { string user_id = 1; }
message TodoAddRequest {
string user_id = 1;
string task = 2;
}
message TodoDeleteRequest {
string user_id = 1;
string id = 2;
}
message TodoObject {
string user_id = 1;
string id = 2;
string task = 3;
}
message TodoChangeEvent {
string idemponcy_id = 1;
TodoObject current = 3;
TodoObject original = 4;
}
message TodoAddResponse { TodoObject todo = 1; }
message TodoListResponse { repeated TodoObject todos = 1; }
message TodoDeleteResponse { string message = 1; }
service TodoService {
rpc TodoAdd(TodoAddRequest) returns (TodoAddResponse);
rpc TodoDelete(TodoDeleteRequest) returns (TodoDeleteResponse);
rpc TodoList(TodoListRequest) returns (TodoListResponse);
} package core:todo@1.0.0;
interface types {
record todo-object {
user-id: string,
id: string,
task: string,
}
record todo-change-event {
idempotency-id: string,
current: todo-object,
original: todo-object,
}
record todo-list-request {
user-id: string,
}
record todo-add-request {
user-id: string,
task: string,
}
record todo-delete-request {
user-id: string,
id: string,
}
record todo-add-response {
todo: todo-object,
}
record todo-list-response {
todos: list<todo-object>,
}
record todo-delete-response {
message: string,
}
variant todo-error {
not-found,
unauthorized,
invalid-input,
internal-error,
}
}
interface todo-service {
use types.{
todo-add-request,
todo-add-response,
todo-delete-request,
todo-delete-response,
todo-list-request,
todo-list-response,
todo-error,
};
todo-add: func(request: todo-add-request) -> result<todo-add-response, todo-error>;
todo-delete: func(request: todo-delete-request) -> result<todo-delete-response, todo-error>;
todo-list: func(request: todo-list-request) -> result<todo-list-response, todo-error>;
} |
/bounty $25000 |
💎 $25,000 bounty • Golem CloudSteps to solve:
Thank you for contributing to golemcloud/golem! Add a bounty • Share on socials
|
/attempt #1201 Options |
By the way, I am already finishing the OpenAPI Export Integration from #1178 should be finished within few hours... |
Would you be interested In something like https://docs.google.com/document/d/1Ru5UlOz-4dz9ors3FKEg2Ac-KxKVqI_wR0EitECp-mo/edit?usp=drivesdk You could use protobuf generators to obtain structs and classes in supported languages, and if we see the other end using protobuf we will serialize as such and vice- versa. Also we will have converters from protobuf to Cap’n a Proto end vice versa. So anyone having gRPC services could easily migrate to this. That could do it in phases as we will be interoperable with protobuf. Using HTTP/3 with QUIC for gRPC with Cap’n Proto and tonic crate brings several potential advantages, especially in scenarios requiring high-performance data exchange and improved reliability over modern networks. Motivation and key advantages: |
/attempt #1201 Options |
/attempt #1201 Options |
Please do not start working on the worker executor part of this until #1150 is done (which is work in progress at the moment). |
Note that there is no real need for a separate OpenAPI definition, as gRPC supports standard REST-JSON transcoding defined within gRPC itself. service TodoService {
rpc TodoAdd(TodoAddRequest) returns (TodoAddResponse) {
option (google.api.http) = {
post: "/components/schemas/Todo/{user_id}"
};
};
rpc TodoDelete(TodoDeleteRequest) returns (TodoDeleteResponse) {
option (google.api.http) = {
delete: "/components/schemas/Todo/{user_id}"
};
};
rpc TodoList(TodoListRequest) returns (TodoListResponse) {
option (google.api.http) = {
get: "/components/schemas/Todo/{user_id}"
};
};
} This approach is supported by many servers, such as Armeria, Microsoft ASP.NET, Google Cloud and gRPC-gateway This is something that can be considered. |
/attempt #1201 Options |
@ilyakharlamov the idea is that you have an OpenAPI spec for something you want to call from a Golem worker, and you get a generated typed-safe way to interact with it, just by providing this spec (which may be originated from a 3rd party). The REST-JSON mapping in gRPC in your example is not helping with this - someone would have to manually create this gRPC definition from the OpenAPI spec. It's actually making more work, if we want to support this as well, which we did not consider earlier. (As it would be a third way to describe a target API) |
Implementation Plan for gRPC and OpenAPI Integration in GolemObjective:Integrate gRPC and OpenAPI support into Golem, enabling type-safe interactions between Golem workers and external services via Protobuf and OpenAPI schemas. The implementation will allow users to easily add gRPC and OpenAPI dependencies and interact with them in a type-safe manner through generated WIT (WASM Interface Types) definitions and dynamic stubs. Key Steps in Implementation:
Expected Outcome:By the end of this implementation, Golem workers will be able to interact with remote gRPC and OpenAPI services in a type-safe way using automatically generated WIT definitions and dynamically linked stubs. This is the high-level overview of the implementation. If approved, I will proceed with the detailed design and development. /attempt #1201 Options |
/attempt #1201 Options |
and in the grpc example comment the file ...
service TodoService {
rpc TodoAdd(TodoAddRequest) returns (TodoAddResponse);
rpc TodoDelete(TodoDeleteRequest) returns (TodoDeleteResponse);
rpc TodoList(TodoListRequest) returns (TodoListResponse);
} ...
interface todo-service {
...
todo-add: func(request: todo-add-request) -> result<todo-add-response, todo-error>;
todo-delete: func(request: todo-delete-request) -> result<todo-delete-response, todo-error>;
todo-list: func(request: todo-list-request) -> result<todo-list-response, todo-error>;
} do not contain any error type.. but the WIT contains are we supposed to generate the error type in some predefined format or search for error keyword in available types? ps: if possible.. it would be easier to communicate via Discord.. I've asked the same question there (https://discord.com/channels/1134448700572319785/1291767182082048040/1320553191762427904) |
@ssddOnTop That looks like a mistake. For gRPC, I think the best we can do is to reflect protocol-level errors. |
hey hey and hey i would love to work on this issue, also if anyone can collaborate on this work that would be great |
/attempt #1201
Options |
/attempt #1201 Options |
/attempt #1201 Options |
As this bounty has been open for 2 months without progress, we are considering withdrawing this bounty. If anyone has completed significant work in progress of this bounty and intends to complete the work in a reasonable timeframe, then please let us know within the next 24 hours! |
Hey @jdegoes! I actually do a LOT with gRPC and OpenAPI, but I've been in the process of a move. I'm absolutely on this - just finally getting settled. Actually, this is in line with some other OSS I'm planning on working on, so very valuable for me to complete as well from an OSS lab perspective. I'm happy to set a reasonable timeline - I'm funemployed through this week and can put my attention to it if it's blocking you. And WASM scheduling - this is oddly right in my wheelhouse, but just been slammed for time! |
Perhaps you could garner more interest in the bounty by offering multiple payments, instead of 1 payment e.g. 3 payments of $15k, $10k and $5k each for 1st, 2nd and 3rd place respectively, instead of one $25k payment? Right now, with only 1 payment on offer, the bounty terms highly favor bounty hunters that learn about this task as soon as it is posted and start working on it immediately because they have time on their hands (read: university students). I imagine you are looking to reward experience and/or skill versus pure grit, so hoping you will consider this feedback for future bounties of this nature. |
@gerred I would say there are really three main challenges:
Finally, I suppose, one additional challenge is that however one maps the OpenAPI/gRPC to WIT must be replicated again in the worker executor, in a different form -- that is, stubs in the host must be created which implement the WIT. So really the same knowledge is being used in two different places (one to generate WIT, the other to generate an implementation that conforms to the WIT and calls the gRPC/OpenAPI API). In my experience this introduces a bit of a mess trying to keep them in sync exactly. |
@gerred Related:
|
@jdegoes That makes sense, I think we're on the same page and was omitting a bit because I'm catching up this morning. I've built out similar platforms and was really glad to see where WIT is. Selfishly, I want to have MCP tools running on this thing as well in the vein of mcp.run. This all make sense, I can stick to that timeline of at least getting to a draft state and then we can close the implementation gap. Agreed re: the syncing. I'll join the community as well, I've been avoiding WASM for a little bit but this was a great excuse to enter back in. |
I think this is probably a good idea, or maybe have some other collaborative process happen. I was excited to get to work on this at the beginning but I abandoned my effort when I saw that someone else seemed to have jumped on this enthusiastically, as I didn't want to develop a whole solution just to have someone beat me to the punch and end up with nothing for the time spent.
|
I have been working on this from last week. I am focusing on translating a Protobuf to WIT. I intend to get this done by end of this week. But, I am not sure of rest of the work required to integrate the translation into golem-cli workflows. I am currently not focusing on OpenAPI. The reason being the spec is not small. |
/attempt #1201 Options |
@jdegoes |
user i mean |
we can assume first n-1 parameters of functions as query params |
for n-1 params we still need to document which are for query params and which are for path params. |
/request can i start working on this |
@gerred @kapilreddy Any update?? |
@jdegoes Hello. Apologies for the delay on replying here. grpc to WIT conversion is in pretty good shape. I have tested it with https://grpcb.in/ Currently I am trying to figure out how to update But, before I do that. I wanted to try out stub generation. |
/request 1201 Golem/GOLEMCLOUD [CapuchaRojo)] [Tech]( Python, Rust) Options |
@kapilreddy Please note that a lot of things changed in the implementation: the stubs are now added dynamically in I note this in the ticket description. You can see how stubs are added for wasm-rpc in the worker executor and copy the same approach (involving using wasmtime types). The gRPC communication will happen in the worker executor through these dynamically added stubs. |
Hi, resp json to rust type rust bindings.rs generated from wit is not implementing this trait. |
but impl deserialize trait dynamically from wit and openapi is bit challenging. possible but time confusing right. |
found this
|
@webbdays It seems you are trying to generate Rust that matches the WIT, but code generation is not on the table for this issue, because a newer approach has been discovered that yields superior usability. See the PR linked in the issue description, which was merged. |
ok. Thanks for pointing that out. |
General approach
I should be ready with these changes by 3rd March. I can pickup OpenAPI integration next. I had some ideas on how to phase the Open API changes. I'll document it later once I am near finishing gRPC changes. Some references that I am using, |
@kapilreddy I’ve been following the discussions and your approach to translating gRPC protobuf to WIT, adding grpc support in static-wasm-rpc, and integrating system tests. I'd love to contribute and assist in any way possible. If there are specific tasks I can take on or areas where you need help, please let me know. Also, I'm interested in the OpenAPI integration you mentioned—I'd be happy to discuss potential phases and contribute to that as well. Looking forward to collaborating! 🚀 |
Changes
Next update expected by March 7th. |
@aditya-sphereoutsourcing You can reach out to me on discord. I am mostly finished with grpc work. But we can work together on something else. |
I want to split this bounty into the gRPC and OpenAPI work separately. This is because gRPC is relatively straightforward and can be done more quickly than OpenAPI, which will have a lot of edge cases and require a lot of testing. It looks like you are the only person working on this, so are you amenable to such a split? |
This is not really how I want this implemented. Instead, since we already have |
@jdegoes Thank you for the clarification on the expectation of the change. @vigoo Had also mentioned this on discord. re: Bounty split: Yes I am good to go ahead with a split. |
@jdegoes
I am positive enough that i can finish it. 💯 😅 |
Translating from proto to WIT is the easy part of this project. Then you need to dynamically implement this WIT in the This involves writing some dynamic linking code in If you don't understand what I am talking about here, then I'm afraid you have zero chance of solving the ticket. |
This specification defines a new feature whereby Golem workers will be able to interact with gRPC and OpenAPI services in a type-safe way, similar to how Golem workers interact with other workers in a type-safe way.
This feature will greatly expand the number of applications that can be built and deployed on Golem and simplify usability of existing Golem applications currently written using lower-level libraries, such as HTTP client libraries.
When fully implemented, Golem users will be able to simply add new gRPC and OpenAPI dependencies, and then immediately begin interacting with them in a type-safe way, through automatically generated WIT definitions that structure the interacts with the remote services, and through automatically and dynamically implemented stubs that provide implementation of these WIT interfaces and which communicate to the underlying gRPC / OpenAPI dependencies.
Background
In Golem's current worker-to-worker communication, WIT interfaces describe the public interface of components, with
wasm-rpc
handling the transformation of these interfaces to support the addressing of specific workers. For external service communication, we need similar but stateless transformations from Protobuf and OpenAPI specifications to WIT.The current process for worker-to-worker communication is as follows:
A
, which depends on a componentB
. The user adds componentB
as a dependency of componentA
, by editing the Golem application manifest file (a YAML file read bygolem-cli
).B
is described by WIT (WASM Interface Types).golem-cli
, using thewasm-rpc
project, can generate a transformed WIT file that is the stateful version of the original WIT exported by componentB
. This stateful aspect allows developers to target specific workers, which is necessary for worker-to-worker communication--but which is not generally necessary for gRPC or OpenAPI, because these protocols are stateless.wasm-rpc
generates and compiles stubs for RPC, which implement the transformed (stateful) WIT, and require Golem host functions for performing the actual RPC. Note that this step is in the process of being simplified, and shortly, the stubs will be dynamically added on the server side, in theworker-executor
, using a custom linker, and this model of dynamic stub generation must be used for both gRPC and OpenAPI support.A
, invoking the transformed WIT, and linking against the stubs, to eliminate the requirement on the transformed WIT. This step is disappearing as worker-to-worker transitions to the server-side, dynamically generated stubs; it will not be necessary for gRPC or OpenAPI support.worker-executor
provides the Golem host functions necessary for RPC.The process for supporting gRPC and OpenAPI will proceed in a similar fashion:
A
, which depends on gRPC defined by ProtobufB
and OpenAPI API defined by schemaC
. The user adds a reference toB
as one dependency of typegrpc
, and a reference toC
as another dependency of typeopenapi
, by editing the Golem application manifest file.golem-cli
, using an extended and enhancedwasm-rpc
, generates a WIT file forB
, corresponding to an idiomatic encoding of the gRPC services into WIT; and another WIT file forC
, corresponding to an idiomatic encoding of the OpenAPI API into WIT.A
, invoking the generated WIT forB
andC
as necessary to access the functionality of APIB
and APIC
.worker-executor
, when executing instances of componentA
, dynamically stubs the WIT interfaces and links them to the instances, allowing instances to interact with the gRPC service and the OpenAPI API.In supporting both gRPC and OpenAPI, there are several major challenges:
worker-executor
is already using to make WASI calls durable (essentially, branching off record/play back mode and reading from / writing to the oplog).Beyond these major challenges, there are several other essential features of the implementation to consider:
golem-cli
, the command-line interface for Golem.wasm-rpc
, for describing worker-to-worker communication.worker-executor
to generate and add the dynamic stubs.worker-executor
, so when a worker is launched, they have what they need to dynamically add the gRPC / HTTP stubs.Input Formats
Common Requirements
Package Translation
Type Mappings
Protobuf and OpenAPI types must be mapped into their most precise WIT types. A sketch of a few possible mappings for Protobuf is shown below:
Note that OpenAPI schemas may embed JSON schemas, which can contain patterns. To the extent possible and reasonable, patterns should be converted into validations that occur in the stubs, to ensure that where possible, local and highly descriptive errors are produced--rather than relying on a remote service to produce a useful error in response to some kind of schema validation failure.
Error Handling
The following sketch of an error type could inform design of a generalized error type. The actual error type used in the implementation must be at least as capable and as expressive as the provided one.
Authentication Types
The following sketches of authentication types could inform design of generalized authentication types. The actual authentication types used in the implementation must be at least as capable and as expressive as these sketches:
gRPC-Specific Requirements
Message Translation
Service Translation
Example:
Must become:
The numerical order of fields in the protobuf MUST correspond to the linear order of fields in WIT.
OpenAPI-Specific Requirements
Schema Translation
Inline Type Translation
{path}-{method}-request-body
{path}-{method}-response-body
{parent-type}-item
{parent-type}-{field-name}
{path}-{method}-params
Example:
Could generate something like:
The exact naming scheme may vary, but must be:
Path Translation
Header Handling
Must specially handle these headers:
All other headers must be mechanically translated to kebab-case option fields.
Resource Function Generation Rules
The following sketches of resource interfaces could inform design of generalized resource handling for REST APIs. The actual interfaces used in the implementation must be at least as capable and as expressive as these sketches:
Naming Conventions
Conflict Resolution
Potential algorithm for resolving name conflicts:
Generated Names
Dynamic Stub Requirements
Dynamic stubs must be added to the
worker-executor
for all of the gRPC and OpenAPI dependencies. These stubs must, of course, match the type signatures of the generated WITs.Durability must be ensured using the same mechanism that is used to provide durability for WASI inside the
worker-executor
(namely, direct interaction with the mode, whether record or playback, and the worker oplog).Testing Requirements
Automated tests are required at the following levels:
golem-cli
withwasm-rpc
), they function together as specified.golem-cli
to theworker-executor
.In particular, there must exist automated tests against REAL gRPC and OpenAPI APIs, which verify both the transformed WIT that is generated, and also which actually invoke the APIs from within a test worker, to verify that the dynamically added stubs in the
worker-executor
are working correctly. Durability tests must be added to verify durability of any gRPC or HTTP interacts that happen from within the generated stubs.The solution will be tested against the following resources:
OpenAPI:
gRPC:
We have several additional OpenAPI and gRPC resources we will be "surprise testing" against to ensure sufficient scope and quality.
Acceptance
We will accept the first solution which, in our sole opinion and estimation:
The text was updated successfully, but these errors were encountered: