Deploy a handler
Serve a route from an already-built WebAssembly component. You declare the
handler in project.cfg, validate the manifest, then sync — the sync step
validates the component blob and activates it against the site policy.
To build a component from scratch, see Write your first handler. To use the host bindings from guest code, see Use handler bindings.
Before you start
- A component built to the
wasm32-wasip2target that exportswasi:http/incoming-handler. Sync rejects a component without this export. - The component file reachable from your project root (here,
dist/api.wasm). - A server built with the
handlersfeature. - Site policy that permits handlers and allows every import you request. The requested imports are intersected with the site’s allowed imports at activation; an import the site does not grant is refused — see Use handler bindings.
1. Declare the handler in project.cfg
Add the handler to the routing.handlers list. Each entry names a route pattern,
the allowed methods, the component file, and the host imports it may use (sql,
wasi:keyvalue, wasi:blobstore, wasi:messaging, plus wasi:http / wasi:io,
which every handler gets):
routing: (
handlers: [
( route: "/api/**", component: "dist/api.wasm",
methods: ["GET", "POST"],
imports: ["sql", "wasi:keyvalue"] ),
],
),
A component receives only the imports it declares here, and only those the site
also grants. Unlisted interfaces (for example wasi:filesystem) are refused even
when named.
2. Validate the manifest
Check the config shape and route table before you deploy:
boatramp validate
project.cfg: routing OK (1 handler: /api/** [GET, POST])
validate checks the manifest. The component blob itself — parseability, the
wasi:http/incoming-handler export, and the import allowlist — is validated at
sync.
3. Sync the deployment
Upload the component and activate it:
boatramp sync ./dist --site my-site
validated dist/api.wasm — exports wasi:http/incoming-handler, imports OK
activated my-site -> 7f3a2b2c — handler /api/**
If the component requests an import the site does not allow, sync rejects the deployment and the previous one stays live.
4. Call the route
curl https://my-site.example/api/health
{"status":"ok"}
A method outside the handler’s methods list returns 405; a path outside the
route pattern falls through to rewrites, then static content.
Reference
- Route and import fields: project.cfg schema.
- Using bindings from guest code: Use handler bindings.
- Build a handler end to end: Write your first handler.