Building a hello-world http app using TinyGo + wasip2
Rajat Jindal
Aug 13th 2024, 09:30AM
In this blog, we will walk through how to implement a simple http handler using WebAssembly
and TinyGo.
This blog post has been updated on May 3rd to work with latest version of TinyGo (v0.37.0) and Wasmtime (v0.32.0).
Prerequisites
In the previous blog, we walked through how to implement a simple hello world app using WebAssembly
and TinyGo. Now, we will extend the app to implement a http handler, and serve it using wasmtime.
To start, lets add github.com/rajatjindal/wasi-go-sdk
as our dependency. This sdk provides an easy to use interface on top of wasi's generated bindings.
Note: This SDK will likely be deprecated in favor of spin-go-sdk once the support for wasip2 is merged.
go mod init
go get github.com/rajatjindal/wasi-go-sdk
go mod tidy
Now, we can modify our main.go
to initialize a http-handler:
package main
import (
"fmt"
"net/http"
"github.com/rajatjindal/wasi-go-sdk/pkg/wasihttp"
)
func init() {
wasihttp.Handle(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("x-wasi-rocks", "true")
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, "Hello Wasi !!")
})
}
func main() {}
and then build it using TinyGo
:
tinygo build -target=wasip2 \
--wit-package $(go list -mod=readonly -m -f '{{.Dir}}' github.com/rajatjindal/wasi-go-sdk)/wit \
--wit-world sdk \
-o main.wasm main.go
There are a few differences between the build commands we used in Hello World app, and this http-handler:
- We explicitly provide argument
--wit-world sdk
. This is required because by defaultTinyGo
targets the wit-worldcli
, which is useful for building cli applications. Thesdk
wit-world is defined here - We provide argument
--wit-package
with a weird looking string as value. That weird looking string actually is a subcommand to fetch the WIT files from the sdk repo. This is required for building components usingTinyGo
.
and now we are ready run it using wasmtime
> wasmtime serve -Scli main.wasm
Serving HTTP on http://0.0.0.0:8080/
We need to provide
-Scli
because we importwasi:cli/environment@0.2.0
in the SDK, and using this option, the wasmtime runtime is configured to link the implementation.
From a different terminal, run the curl:
curl -v http://0.0.0.0:8080/
* Trying 0.0.0.0:8080...
* Connected to 0.0.0.0 (127.0.0.1) port 8080
> GET / HTTP/1.1
> Host: 0.0.0.0:8080
> User-Agent: curl/8.4.0
> Accept: */*
>
< HTTP/1.1 200 OK
< x-wasi-rocks: true
< transfer-encoding: chunked
< date: Tue, 13 Aug 2024 03:52:46 GMT
<
Hello Wasi !!
Congratulations !! We just executed our first http handler using WebAssembly + TinyGo + Wasmtime.