WASM

Use WASM middleware in your HTTP pipeline

WebAssembly is a way to safely run code compiled in other languages. Runtimes execute WebAssembly Modules (Wasm), which are most often binaries with a .wasm extension.

The Wasm HTTP middleware allows you to rewrite a request URI with custom logic compiled to a Wasm binary. In other words, you can extend Dapr using external files that are not pre-compiled into the daprd binary. Dapr embeds wazero to accomplish this without CGO.

Wasm modules are loaded from a filesystem path. On Kubernetes, see mounting volumes to the Dapr sidecar to configure a filesystem mount that can contain Wasm modules.

Component format

  1. apiVersion: dapr.io/v1alpha1
  2. kind: Component
  3. metadata:
  4. name: wasm
  5. spec:
  6. type: middleware.http.wasm.basic
  7. version: v1
  8. metadata:
  9. - name: path
  10. value: "./hello.wasm"
  11. - name: poolSize
  12. value: 1

Spec metadata fields

Minimally, a user must specify a Wasm binary that contains the custom logic used to rewrite requests. An instance of the Wasm binary is not safe to use concurrently. The below configuration fields control both the binary to instantiate and how large an instance pool to use. A larger pool allows higher concurrency while consuming more memory.

FieldDetailsRequiredExample
pathA relative or absolute path to the Wasm binary to instantiate.true“./hello.wasm”
poolSizeNumber of concurrent instances of the Wasm binary. Default: 10false1

Dapr configuration

To be applied, the middleware must be referenced in configuration. See middleware pipelines.

  1. apiVersion: dapr.io/v1alpha1
  2. kind: Configuration
  3. metadata:
  4. name: appconfig
  5. spec:
  6. httpPipeline:
  7. handlers:
  8. - name: wasm
  9. type: middleware.http.wasm.basic

Generating Wasm

This component allows you to rewrite a request URI with custom logic compiled to a Wasm using the waPC protocol. The rewrite function receives the request URI and returns an update as necessary.

To compile your Wasm, you must compile source using a waPC guest SDK such as TinyGo.

Here’s an example in TinyGo:

  1. package main
  2. import "github.com/wapc/wapc-guest-tinygo"
  3. func main() {
  4. wapc.RegisterFunctions(wapc.Functions{"rewrite": rewrite})
  5. }
  6. // rewrite returns a new URI if necessary.
  7. func rewrite(requestURI []byte) ([]byte, error) {
  8. if string(requestURI) == "/v1.0/hi" {
  9. return []byte("/v1.0/hello"), nil
  10. }
  11. return requestURI, nil
  12. }

If using TinyGo, compile as shown below and set the spec metadata field named “path” to the location of the output (ex “example.wasm”):

  1. tinygo build -o example.wasm -scheduler=none --no-debug -target=wasi example.go

Last modified January 4, 2023: fix links in wasm middleware docs (#3029) (a1d4b22c)