Skip to main content
Version: 0.82

Create

Changing in 1.0+

The term "actor" is deprecated. wasmCloud 1.0 and later simply refer to this entity as a component, reflecting wasmCloud's standardization around WebAssembly components. You can learn more here.

We provide example templates for creating actors in Rust and TinyGo. You can use these templates to create a new actor project, or you can use them as a reference for creating your own actor from scratch. As other languages are updated to use the same component APIs that wasmtime uses, we will add templates for those languages as well.

Creating the scaffold for a new actor in Rust is easy. We will create an actor that accepts an HTTP request and responds with "Hello from Rust!". To create your new actor project, change to the directory where you want the project to be created, and enter the command below. The first term on the command (hello) is the project name. If you choose a different project name, the name of the subdirectory and some symbols in the generated code will be different from the example code in this guide.

bash
wash new actor hello --subfolder examples/rust/actors/http-hello-world --git wasmcloud/wasmcloud --branch 0.82-examples

Let's change into the newly-created folder hello and take a look at the generated project. The file src/lib.rs includes a wit-bindgen generate macro, an imports section, a struct HttpServer, and an impl block that implements the Guest trait for the actor struct. Let's walk through these sections in detail.

rust
wit_bindgen::generate!({
    world: "hello",
    exports: {
        "wasi:http/incoming-handler": HttpServer,
    },
});

This shows us that we're using a core wasmCloud package called wit-bindgen to generate the types and bindings for our actor. The world term is the name of the wit world we're generating from under ./wit, and the exports term declares the functions the component will export. In this case, we're declaring that the actor will implement the wasi:http/incoming-handler capability interface, and that the implementation struct is named HttpServer.

Note the two lines near the top of the source code file:

rust
use exports::wasi::http::incoming_handler::Guest;
use wasi::http::types::*;

These two imports are bringing in the Guest trait to implement our function to be called whenever an incoming HTTP request is received, and the types that we'll use to interact with the HTTP request and response. These are the only two imports that we need to interact with the HTTP server capability.

rust
struct HttpServer;

impl Guest for HttpServer {
    fn handle(_request: IncomingRequest, response_out: ResponseOutparam) {
        let response = OutgoingResponse::new(Fields::new());
        response.set_status_code(200).unwrap();
        let response_body = response.body().unwrap();
        response_body
            .write()
            .unwrap()
            .blocking_write_and_flush(b"Hello from Rust!\n")
            .unwrap();
        OutgoingBody::finish(response_body, None).expect("failed to finish response body");
        ResponseOutparam::set(response_out, Ok(response));
    }
}

Within the handle method, the actor receives the HTTP request, creates an OutgoingResponse and writes that response out back to the requesting http client (such as a curl command or a web browser).

If you use an IDE that comes with code completion and hover-tooltips, you'll be able to see documentation and get strongly-typed guidance as you develop code to interact with the WASI interfaces.

info

The above component example works without any modification in wasmCloud, but is specifically built using standard WebAssembly tooling. You do not need to use a wasmCloud specific SDK to build actors, and the above example will work directly with any WebAssembly runtime that supports the Wasm component model.

Something's missing

Before we get into modifying the scaffolding to create the rest of this actor, take a look at what's not included in this code. This code returns an abstraction of an HTTP response. It is not tightly coupled to any particular HTTP server. Furthermore, you don't see the port number or server configuration options anywhere in the code. Finally, you can scale and compose this actor any way you see fit without ever having to recompile or redeploy it.

This method of interface driven development is a core piece of the wasmCloud project philosophy. You should be able to write business logic in a language of your choice without having to worry about the non-functional requirements of your application, letting you configure loosely coupled abstractions at runtime. Moving on past our project scaffolding, the next step is to build and run our actor.