Welcome to the new Golem Cloud Docs! 👋
Documentation
Component Interface

Component Interface

This section describes how your Golem Component's public interface is defined using the WASM component model and how is it mapped into the Golem API.

The page is divided into two major sections by tiers, as the ability to define your component's interface is one of the primary differentiators between our different language tiers. Read the Building Components page for more information.

This page will use Golem CLI parameter names when talking about how to invoke functions, but the same rules apply when using the REST API too.

Tier 1 languages

Tier 1 languages use the WASM component model's tooling to define their interface using WIT files. Please read the official design document of the WIT format (opens in a new tab) to learn what it is capable of.

For each tier 1 language there is a binding generator tool that takes the WIT definition and generates the appropriate binding code in the given guest language. Read Building Components for more information about how these tools work.

The WIT definition is also embedded in the compiled WASM that you upload to Golem. This is how Golem knows what the exported functions are, and it can validate the provided parameters to make sure they have the correct type.

Function names

This section explains how you can map the exported function names from your WIT definition to fully qualified names to be passed in the --function parameter when invoking an instance.

The component you define has a WIT package, specified in the top of your WIT definition.

For example if you generated your code using golem new and did not specify a custom package name, it will be:

package golem:component

This package name can optionally specify a package version as well, such as:

package golem:component@0.3.2

You can have any other pair of names following the above syntax.

The WIT definition should contain a single world (otherwise the world to be used have to be specified for the tools used during compilation). The name of this world does not matter for Golem - it won't be part of the function's fully qualified name.

For example it can be:

world my-component-world {
  // ...
}

In this world you can either export

  • one or more interface
  • or one or more functions directly

The following example demonstrates both:

package golem:component;
 
interface api {
  record product-item {
    product-id: string,
    name: string,
    price: float32,
    quantity: u32,
  }
 
  add-item: func(item: product-item) -> ();
  remove-item: func(product-id: string) -> ();
}
 
world my-component-world {
  export api;
  export dump: func() -> result<string, string>;
}

The name of the interface(s) and function(s) are completely user defined, there are no rules to follow other than the syntax rules of WIT itself.

In the above example we have 3 exported functions and we can refer to them in the --function parameter with the following fully qualified names, consisting of the package name and the exported path:

  • golem:component/api.{add-item}
  • golem:component/api.{remove-item}
  • golem:component.{dump}

Note that the syntax is the same as the one used for the use statements in the WIT file.

Resources

WIT specifications also allow the definition of resources. These are constructed via special constructors, have methods, and can also have associated static functions. Golem supports exporting resources, enabling an alternative of having a separate worker for each entity. When exporting resources, a single worker may own an arbitrary number of instances of the exported resource, and the method invocations's first parameter must be the resource handle returned by the invoked constructor.

There is a special naming syntax provided by Golem that makes it more convenient to invoke resource constructors and methods. Take the following example:

package golem:component;
 
interface api {
  resource counter {
    constructor(name: string);
    inc-by: func(value: u64);
    get-value: func() -> u64;
 
    merge-counters: static func(counter1: counter, counter2: counter, name: string) -> counter;
  }
}
 
world my-world {
  export api;
}

For this WIT specification, the following function names are valid when using Golem's invocation API or CLI:

  • golem:component/api.{counter.new} - refers to the above defined constructor
  • golem:component/api.{counter.inc-by}
  • golem:component/api.{counter.get-value}
  • golem:component/api.{counter.merge-counters}
  • golem:component/api.{counter.drop} - special function that drops the instance while the worker continues running

Implicit resource creation

With the above described naming conventions it is possible to manually create instances of resources, and then use the returned resource handle to invoke methods on them.

There is an easier way to work with resources in Golem, that assumes that a given resource instance is associated with the constructor parameters it is created with. This way it is possible to target a specific instance just by using the function name, and the resource instance will be automatically selected or created if it does not exist yet.

To use this feature, pass the target constructor parameters in the function name's resource name part in parentheses. For example, with the above defined counter resource we can immediately create and a new counter and increment it by calling:

  • golem:component/api.{counter("my-counter").inc-by}

This will create a new counter instance with the name my-counter and increment it. If the counter with the name my-counter already exists, it will be used.

The syntax for passing inlined parameters to the constructor is using the WAVE syntax (opens in a new tab).

Parameters and results

This section defines the mapping from the different types you can use or define in your WIT definition and the JSON you pass to the --parameters parameter of the invocation and see as your invocation's result.

When invoking a function, the JSON passed to --parameters always has to be a JSON array. Each element of this array corresponds to one parameter of the function. So to call a function without any parameters pass an empty array ([]). The result of a function invocation is also a JSON.

The following table maps types you can use in WIT to their JSON encoding:

WIT typeJSON typeDescription
boolJSON booleanPrimitive boolean type
u8JSON numberUnsigned 8-bit integer
s8JSON numberSigned 8-bit integer
u16JSON numberUnsigned 16-bit integer
s16JSON numberSigned 16-bit integer
u32JSON numberUnsigned 32-bit integer
s32JSON numberSigned 32-bit integer
u64JSON numberUnsigned 64-bit integer
s64JSON numberSigned 64-bit integer
float32JSON number32-bit floating point number
float64JSON number64-bit floating point number
charJSON numberASCII character
stringJSON stringString
<t1, t2, ...>JSON array of the items: [v1, v2, …]Tuple of types t1, t2, …
list<t>JSON array of the items: [item1, item2, …]List of items of type t
option<t>null if not defined the inner value if definedAn option of type t
result<t, e>Object with either an ok or an err field:{ "ok": ... } { "err": ... } If t or e is unit (_ in WIT) then use null in the JSON, for example { "ok": null }.Type representing either a success of type t or a failure of type e
handlenot supported yet
idnot supported yet
recordJSON object where for each record field there is a field with the same name.Record containing a series of named fields.
variantJSON object with a single field that has the name of one of the variants. For example: { "child": 10 }Variant that can be one of the specified types, discriminated by a case name.
enumJSON string holding the name of the enum, for example "low"Enum is a set of possible named values
flagsA JSON array of stringsSet of possible name values, where you can select more than one of them.
handlea JSON string that starts with the resource owner's worker uri, followed by a slash and a numeric resource id: "worker://component-id/worker-name/resource-id"Points to a resource created on a given worker

Tier 2 languages

For Tier 2 languages you cannot define more than one function to be exported. The function that Golem will run is your program's main function, without passing any arguments or getting any result values.

Function names

The function name for tier 2 languages that you need to pass to the --function parameter of Golem CLI is always:

  • wasi:cli/run@0.2.0.{run}

Parameters and results

As you cannot define any parameter or result types in tier 2 the only option is to use the stdio mode or the stdio event loop mode.

This is enabled in the Golem CLI using the --use-stdio command when invoking an instance.

Once it is enabled, the JSON you pass to the --parameters parameter will be directly available to read from the worker's standard input, and Golem expects the run function to write a result JSON to the standard output.

No further type checking is performed, but both the input and the output is expected to be JSONs.