|
1 | 1 | <div align="center"> |
2 | 2 | <h1><code>go-pkg</code></h1> |
3 | 3 | <p> |
4 | | - <strong>Golang packages for the Bytecode Alliance <a href="https://github.com/bytecodealliance/componentize-go">componentize-go</a> project</strong> |
| 4 | + <strong>The Go library for building WebAssembly components with <a href="https://github.com/bytecodealliance/componentize-go">componentize-go</a></strong> |
5 | 5 | </p> |
6 | 6 | <strong>A <a href="https://bytecodealliance.org/">Bytecode Alliance</a> project</strong> |
7 | 7 | <p> |
|
15 | 15 |
|
16 | 16 | # Overview |
17 | 17 |
|
18 | | -This is a set of Golang packages for the Bytecode Alliance componentize-go project. |
| 18 | +Module `go.bytecodealliance.org/pkg` is the Go library for Wasm components. It adapts standard-library interfaces (`net/http`, `log/slog`) to standard `wasi:*` interfaces and ships the committed bindings and WIT worlds needed to build HTTP components with [componentize-go](https://github.com/bytecodealliance/componentize-go). The use of this package significantly reduces the number of files generated and committed for a typical go application. |
| 19 | + |
| 20 | +The library targets two worlds defined in [`wit/world.wit`](./wit/world.wit): |
| 21 | + |
| 22 | +- **`bytecodealliance:pkg/wasip2`** (default): a sync WASI P2 component exporting `wasi:http/incoming-handler@0.2.8`, buildable with stock Go. |
| 23 | +- **`bytecodealliance:pkg/wasip3`** (opt-in): an async WASI P3 component exporting `wasi:http/handler@0.3.0` with streaming bodies and native concurrency. |
| 24 | + |
| 25 | +## Packages |
| 26 | + |
| 27 | +| Package | Description | |
| 28 | +| --- | --- | |
| 29 | +| `wasihttp` | `net/http` adapter for `wasi:http`: serve incoming requests with a standard `http.Handler` and send outbound requests through an `http.RoundTripper`. One API, two implementations selected by build tag (see below). | |
| 30 | +| `wasilog` | `slog.Handler` implementation over `wasi:logging`. | |
| 31 | +| `wasiconfig` | Helpers over `wasi:config/store`. | |
| 32 | +| `wit/types`, `wit/runtime`, `wit/async` | Core WIT value types (option, result, tuple, stream, future) and the canonical-ABI runtime support used by generated bindings. | |
| 33 | +| `imports/...` | Committed generated bindings for the `wasi:*` interfaces imported by the two worlds (both the 0.2.8 and 0.3.0 families). | |
| 34 | +| `exports/...` | Per-world generated `//go:wasmexport` glue and export trampolines. | |
| 35 | + |
| 36 | +Bindings under `imports/` and `exports/` are generated by |
| 37 | +[`regenerate_bindings.sh`](./regenerate_bindings.sh) — do not edit them. |
| 38 | + |
| 39 | +## Updating WIT dependencies |
| 40 | + |
| 41 | +The `wasi:*` WIT packages under `wit/deps/` are vendored verbatim from the WebAssembly package registry using [wkg](https://github.com/bytecodealliance/wasm-pkg-tools). To update a dependency: |
| 42 | + |
| 43 | +1. Bump its version in [`fetch_wit_deps.sh`](./fetch_wit_deps.sh) and in |
| 44 | + [`wit/world.wit`](./wit/world.wit). |
| 45 | +2. Re-fetch the vendored WIT: |
| 46 | + |
| 47 | + ```console |
| 48 | + $ ./fetch_wit_deps.sh |
| 49 | + ``` |
| 50 | + |
| 51 | +3. Regenerate the committed bindings and commit everything together: |
| 52 | + |
| 53 | + ```console |
| 54 | + $ ./regenerate_bindings.sh |
| 55 | + ``` |
| 56 | + |
| 57 | +> **Note**: the script uses `wkg get` with exact versions rather than |
| 58 | +> `wkg wit fetch` because the library intentionally depends on two versions |
| 59 | +> of several packages (e.g. `wasi:http@0.2.8` and `wasi:http@0.3.0`), and |
| 60 | +> `wkg wit fetch` resolves at most one version per package name. |
| 61 | +
|
| 62 | +## The `componentizego_async` build tag |
| 63 | + |
| 64 | +`wasihttp` compiles to one of two implementations; the exported API is identical under both: |
| 65 | + |
| 66 | +- **Default (no tag)**: sync WASI P2 (`wasi:http@0.2.8`). Matches the `bytecodealliance:pkg/wasip2` world. |
| 67 | +- **`-tags componentizego_async`**: async WASI P3 (`wasi:http@0.3.0`) with streaming bodies and native concurrency. Matches the `bytecodealliance:pkg/wasip3` world. |
| 68 | + |
| 69 | +componentize-go sets the tag automatically when building an async world. |
| 70 | + |
| 71 | +## Quickstart |
| 72 | + |
| 73 | +```go |
| 74 | +package main |
| 75 | + |
| 76 | +import ( |
| 77 | + "net/http" |
| 78 | + |
| 79 | + "go.bytecodealliance.org/pkg/wasihttp" |
| 80 | +) |
| 81 | + |
| 82 | +func init() { |
| 83 | + wasihttp.HandleFunc(func(w http.ResponseWriter, r *http.Request) { |
| 84 | + w.Write([]byte("Hello, component!")) |
| 85 | + }) |
| 86 | +} |
| 87 | + |
| 88 | +func main() {} |
| 89 | +``` |
| 90 | + |
| 91 | +Add componentize-go as a Go tool and build: |
| 92 | + |
| 93 | +```console |
| 94 | +$ go get -tool github.com/bytecodealliance/componentize-go |
| 95 | +$ go tool componentize-go build |
| 96 | +``` |
| 97 | + |
| 98 | +The default world (`bytecodealliance:pkg/wasip2@0.1.0`) is declared in [`componentize-go.toml`](./componentize-go.toml) and discovered automatically. To build the async WASI P3 world instead: |
| 99 | + |
| 100 | +```console |
| 101 | +$ go tool componentize-go -w bytecodealliance:pkg/wasip3 build |
| 102 | +``` |
| 103 | + |
| 104 | +## Benchmarks |
| 105 | + |
| 106 | +Pure-Go conversion logic (header conversion and friends) has microbenchmarks that run on the host: |
| 107 | + |
| 108 | +```console |
| 109 | +$ go test -bench=. -benchmem ./... |
| 110 | +``` |
| 111 | + |
| 112 | +Packages that call `wasi:*` imports only link on wasm targets, so the benchmarks live in host-compilable packages (e.g. `internal/httpconv`). |
| 113 | + |
| 114 | +For A/B comparisons use [benchstat](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat): collect ≥10 samples per side with the test filter disabled, then compare: |
| 115 | + |
| 116 | +```console |
| 117 | +$ go test -bench=. -benchmem -count=10 -run='^$' ./... > old.txt |
| 118 | +$ # ... apply your change ... |
| 119 | +$ go test -bench=. -benchmem -count=10 -run='^$' ./... > new.txt |
| 120 | +$ benchstat old.txt new.txt |
| 121 | +``` |
19 | 122 |
|
20 | 123 | ## Questions? |
21 | 124 |
|
22 | 125 | Ask over in the Bytecode Alliance <a href="https://bytecodealliance.zulipchat.com">Zulip</a>. |
23 | 126 |
|
24 | 127 | ## Contributing |
25 | 128 |
|
26 | | -See [CONTRIBUTING.md](./CONTRIBUTING.md) for more information about contributing |
27 | | -to this repository. |
| 129 | +See [CONTRIBUTING.md](./CONTRIBUTING.md) for more information about contributing to this repository. |
0 commit comments