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.
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.