Define an API definition
To begin with, let's build an API over the functions in the shopping cart example (available via golem-cli new --example rust-example-shopping-cart
):
$ golem-cli component get --component-name cart
Component with URN urn:component:c57de1ee-fbe5-4068-a67d-908addc8aa44. Version: 0. Component size is 2900607 bytes.
Component name: cart.
Exports:
golem:component/api.{initialize-cart}(user-id: string)
golem:component/api.{add-item}(item: record { product-id: string, name: string, price: float32, quantity: u32 })
golem:component/api.{remove-item}(product-id: string)
golem:component/api.{update-item-quantity}(product-id: string, quantity: u32)
golem:component/api.{checkout}() -> variant { error(string), success(record { order-id: string }) }
golem:component/api.{get-cart-contents}() -> list<record { product-id: string, name: string, price: float32, quantity: u32 }>
Here is an example of an API definition, which we will use to expose an HTTP API over the function golem:component/api.{get-cart-contents}
.
id: my-shopping-cart-v1
draft: true
version: 0.0.4
routes:
- method: Get
path: /v4/{user-id}/get-cart-contents
binding:
type: wit-worker
componentId:
componentId: dba38841-013a-49fa-a1dc-064949832f0c
version: 0
workerName: |
let user: u64 = request.path.user-id;
my-worker-${user}
response: |
let result = golem:it/api.{get-cart-contents}();
{status: 200u64, body: result}
Please use this as a reference instead of using it with zero changes. For example, you might need to give a different
version, componentId etc (explained below). You can get the component
details including componentId
by running golem-cli component list
command.
The API definition's fields have the following meaning:
Field | Description |
---|---|
id | This field represents the unique identifier for the API definition. In this case, it is set to "shopping-cart-v1". |
version | This field indicates the version of the API definition. Here, it is set to "0.0.3". |
routes | This field contains an array of route objects, each representing a specific endpoint definition. |
method | Indicates the HTTP method associated with the route. In this example, it is set to "Get", indicating that this route handles GET requests. |
path | Specifies the URL path pattern for the route. It may include path parameters enclosed in curly braces. Here, the path is /{user-id}/get-cart-contents , indicating that this route handles requests to retrieve the contents of a shopping cart for a specific user. |
binding | This object contains information about how the request should be handled by the Golem worker. |
Golem Binding
Let's break down the binding object.
Field | Description |
---|---|
type | Specifies the type of binding. Here, it is set to "wit-worker", indicating that the binding involves a Golem worker. |
componentId | Provides the component ID associated with the worker binding. As you can see the the golem-worker |
workerName | Specifies the Name of the Golem worker responsible for handling the request. Here it is my-worker-${request.path.user-id} . The value that is wrapped in code block (starting with ${ and ending with } ) will be a Rib expression. Here request.path.user-id is a valid Rib expression where it selects the field path from the request block, and further selects user-id from it. |
response | The response field here is a Rib expression that allows you to call any worker function and manipulates its output. |
Note that workerName and response are actually rib expressions. It gives you the flexibility to make necessary changes to the input and output to a worker function, as well as dynamically create a worker name.
If your worker name is a constant, the you can simply make it a constant string such as "foo"
. Please note that it has to be quoted for it a valid Rib string.
See the Rib reference for the full reference of the binding language.
In this example, the following Rib expression defines the request:
let result = golem:it/api.{get-cart-contents}();
{status: 200u64, body: result}
The first line is about calling the worker-function and assigning its result to the variable result
. The last line is a WASM record where you are mapping to the response. Here body is result
itself.
That means, we are not manipulating the result returned by the function, and simply forward it as response body. Status is 200u64. u64
is the type of the number
as Rib is typed and it needs to know the full type of the WASM record. 200u64
is equivalent to let x: u64 = 200; x;
in Rib.
As mentioned above, see the Rib reference to know more about Rib language.