Skip to main content
Version: 1.x

Interfaces

Overview

In wasmCloud, components and providers communicate through interfaces: contracts that define the relationships between entities. These interfaces come in two kinds:

  • Well-known interfaces are common standards (such as WebAssembly System Interface (WASI) APIs) or wasmCloud interfaces (core functionalities like wasmcloud-messaging) supported out-of-the-box by wasmCloud hosts.
  • Custom interfaces are user-created contracts that make it possible to extend and tailor how wasmCloud components and providers interact with one another.

In all cases, wasmCloud interfaces are defined using the interface description language WebAssembly Interface Type (WIT).

WebAssembly Interface Type (WIT)

WebAssembly Interface Type (WIT) is an open standard maintained as part of the Component Model by the W3C WebAssembly Community Group.

WIT enables WebAssembly components to define the functions they expose to external entities ("exports") and the functionalities they require ("imports") in .wit files.

Packages, namespaces, and versions

Interfaces defined in WIT are organized into packages. Packages must include a namespace and identifier.

Namespace and package in a WIT file

Optionally, WIT packages may include a version using semantic versioning.

Why 0.2.0-draft?

The version for the example above is 0.2.0-draft. WASI proposals move through three phases. Once a proposal reaches Phase 3, it may be included in the standard API group of WASI 0.2. The wasi-keyvalue interface above is at Phase 2.

In wasmCloud, you will often see packages belonging to the wasmcloud and wasi namespaces. You may also create custom interfaces with arbitrary namespaces. Packages with different namespaces may be mixed and matched freely, and the contents of a given package may be spread across multiple files.

A common organizational pattern divides a package into:

  • types.wit
  • imports.wit
  • world.wit
  • my-interface-name.wit

An interface may also have a deps folder holding WIT files for other WIT files used as dependencies in your interface.

For more information on organizing an interface, see Creating an interface.

Worlds

The highest-level contract in a WIT interface is called a world. A WIT world is akin to a complete description of a component, defining the imports and exports that enable the component to interact other entities. Here is a simple example of a world:

wit
package wasmcloud:demo;

world demo {
  import wasi:logging/logging; 

  export wasi:http/incoming-handler@0.2.0;
}

This is the top-level world for a hypothetical component that imports on the logging interface from WASI Logging and exports (or exposes a function on) the incoming-handler interface from WASI HTTP. This enables the component to be invoked (and respond) via HTTP and to use logging functionality.

There are often at least two worlds defined in a package. A common convention is to have an imports world and the world components typically target.

In a wasmCloud component project, it is conventional to include a top-level WIT world at the root of a wit folder in the project directory. At the project root, a wasmcloud.toml configuration file tells the wash build tool which top-level WIT world to compile into a component.

Interfaces

An interface is a collection of types and functions scoped to a package which can be used within a world. Interfaces are the only place that a type can be defined. Packages may contain multiple interfaces.

Interfaces represent the lower-level vocabulary of the contract between entities. Worlds may also refer to other worlds, which themselves may refer to interfaces or still "deeper" worlds. Here is the incoming-handler interface imported by the world above:

wit
/// This interface defines a handler of incoming HTTP Requests. It should
/// be exported by components which can respond to HTTP Requests.
interface incoming-handler {
  use types.{incoming-request, response-outparam};

  /// This function is invoked with an incoming HTTP Request, and a resource
  /// `response-outparam` which provides the capability to reply with an HTTP
  /// Response. The response is sent by calling the `response-outparam.set`
  /// method, which allows execution to continue after the response has been
  /// sent. This enables both streaming to the response body, and performing other
  /// work.
  ///
  /// The implementor of this function must write a response to the
  /// `response-outparam` before returning, or else the caller will respond
  /// with an error on its behalf.
  handle: func(
    request: incoming-request,
    response-out: response-outparam
  );
}

When two entities import and export respectively on the same interface (such as incoming-handler), they can be linked so that once invoked, they interact according to the contract defined in the interface.

Interface diagram

For more information on using WIT, see our Developer Guide page on Creating an interface.

WIT without WebAssembly

In spite of the name, WIT isn't limited to WebAssembly: wasmCloud also uses WIT to define the interfaces used by providers and host functions written in Rust or Go. It is entirely possible, for example, to create a Rust or Go binary that uses WIT interfaces over the wRPC (WIT over RPC) protocol.

Well-known interfaces

wasmCloud supports interfaces belonging to WebAssembly System Interface (WASI) 0.2 in addition to a selection of interfaces proposed for inclusion in WASI, and interfaces belonging to the wasmCloud host.

WASI interfaces

WASI 0.2 includes these APIs, all available for use with wasmCloud 1.0:

APIVersions
https://github.com/WebAssembly/wasi-io0.2.0
https://github.com/WebAssembly/wasi-clocks0.2.0
https://github.com/WebAssembly/wasi-random0.2.0
https://github.com/WebAssembly/wasi-filesystem*0.2.0
https://github.com/WebAssembly/wasi-sockets*0.2.0
https://github.com/WebAssembly/wasi-cli0.2.0
https://github.com/WebAssembly/wasi-http0.2.0
Sensitive interfaces

As a security-first platform, wasmCloud provides stubbed implementations of wasi-filesystem and wasi-sockets that don't truly interact with the host system. For functionality that depends on these interfaces, we recommend using wasi-virt to virtualize your component. Learn more about using WASI Virt with wasmCloud on the Virtualize developer page.

Additionally, wasmCloud supports proposed WASI APIs that are in the process of implementation and standardization:

APIVersions
https://github.com/WebAssembly/wasi-blobstore0.2.0-draft
https://github.com/WebAssembly/wasi-keyvalue0.2.0-draft
https://github.com/WebAssembly/wasi-logging[proposal]

wasmCloud interfaces

Well-known interfaces include two APIs built specifically for wasmCloud:

APIVersions
wasmcloud:bus1.0.0
wasmcloud:messaging1.0.0
  • wasmcloud:bus provides advanced link configuration only available in wasmCloud.
  • wasmcloud:messaging facilitates communication through message brokers.

Custom interfaces

WASI interfaces are ultimately common standards using WIT, but wasmCloud enables you to build custom WIT interfaces and communicate between components in the way best-suited to your requirements.

Here is an example of a greeter interface defined in WIT:

wit
package local:greeter-demo; // <namespace>:<package>

interface greet { // interface <name of interface>
  greet: func(name: string) -> string; // a function named "greet"
}

world greeter {
  export greet; // make the `greet` function available to other components/the runtime
}

While reading the spec is the best way to learn about WIT, it is also designed to be easy to understand at a glance. WASI interfaces written in WIT contain their own documentation and are useful to consult as examples.

Compared to gRPC and Smithy...

While similar frameworks and languages like gRPC and Smithy are meant to perform over network boundaries, WIT is in-process, and performs at near-native speed.

Interface-driven development

Interface-driven development (IDD) is a development approach that focuses on defining what capabilities components require before the specifics of how you will meet those needs.

Systems developed using IDD—especially distributed systems—are loosely coupled, robust, and maintainable.

Keep reading

Continue to learn more about how the wasmCloud host, or...