Skip to content

Latest commit

 

History

History
140 lines (92 loc) · 4.48 KB

File metadata and controls

140 lines (92 loc) · 4.48 KB

WASI http-hello-world in JavaScript

This folder contains a WebAssembly Javascript component that uses wasi:http for enabling HTTP handlers in Javascript.

It uses jco to:

  • Generate a WebAssembly component (via jco componentize) that can be executed by a WebAssembly runtime (ex. wasmtime serve)

Quickstart

Dependencies

First, install required dependencies:

npm install

Note

As this is a regular NodeJS project, you can use your package manager of choice (e.g. yarn, pnpm)

At this point, since this project is just NodeJS, you could use the module from any NodeJS project or browser project where appropriate.

That said, we'll be focusing on building the JS code we've written so far into a WebAssembly binary, which can run anywhere WebAssembly runtimes are supported, including in other languages, and the browser.

Building the WebAssembly component

We can build a WebAssembly component binary out of this JS project with jco:

npm run build

A WebAssembly binary will be written to string-reverse.wasm.

Serving web requests with the WebAssembly component

To run the component and serve requests we can either use jco or wasmtime:

$ jco serve http-hello-world.wasm
Server listening on 8000...

Warning

jco serve is meant to be used for local/development environments, not production use cases.

Similarly you can also use wasmtime:

$ wasmtime serve -S common http-hello-world.wasm
Serving HTTP on http://0.0.0.0:8080/

With either approach, you can use curl the appropriate URL to trigger your WebAssembly component.

Note

The implementations of jco serve and wasmtime serve are what actually fulfill all the imports of your component (see combined/merged world root above), and use the wasi:http/incoming-handler export to make web serving actually happen.

How it works

Exploring this Component WIT

As WebAssembly components are powered by a WebAssembly Interface Types ("WIT")-first workflow, making a HTTP handler component in WebAssembly requires creating a WIT contract to represent that component.

This folder contains a wit directory (by convention) with the following content in component.wit:

package example:http-hello-world;

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

Note

See wit/component.wit

For more information on the WIT syntax, see WIT design docs

We make use of the WebAssembly System Interface ("WASI") HTTP interface here, pulling in pre-established interfaces interfaces for serving incoming HTTP requests.

Resolving references WebAssembly types

As we intend to use the WASI HTTP interface, we need to pull in WIT interface(s) and types that are referred to by the wasi:http/incoming-handler interface.

One way fo doing this is downloading the WIT from Bytecode Alliance repositories, using [wkg, from the bytecodealliance/wasm-pkg-tools][wkg].

With a top level world in wit/component.wit, we can easily fetch all automatically-resolvable interfaces:

wkg wit fetch

Note

Standard interfaces are automatically resolvable, but if custom interfaces are used, you'll need to configure wkg so it knows where to find the relevant WIT information.

Building our component

To turn our JS into a WebAssembly component, we can use jco componentize:

jco componentize http-hello-world.js --wit wit/ --world-name component --out http-hello-world.wasm

Note

For ease, you can do all of this with pnpm build or npm run build, or your npm-compatible build tool of choice.

You should see output like the following:

pnpm build

> http-hello-world-wasm@ build /path/to/jco/examples/components/http-hello-world
> jco componentize http-hello-world.js --wit wit/ --world-name component --out http-hello-world.wasm

OK Successfully written http-hello-world.wasm.

Now that your component has been built, we can do alot of things to inspect it. Here are a few:

➜ file http-hello-world.wasm
http-hello-world.wasm: WebAssembly (wasm) binary module version 0x1000d