Quickstart
Build, test, deploy, and serve your first Switchboard rule in five minutes, no object store required.
This tutorial takes you from an empty directory to a running proxy that hot-reloads your rule. It uses the file:// registry, so there is nothing to provision.
Prerequisites
- Go 1.22+: rules are plain Go packages.
- TinyGo: compiles rules to WebAssembly. Install it from the TinyGo guide.
- The Switchboard CLI:
go install github.com/ethndotsh/switchboard/cmd/switchboard@latest
Build and deploy a rule
Scaffold a project
switchboard init creates a rule project with a working rule, a test suite, and a config file:
mkdir my-rules && cd my-rules
switchboard init --name my-rules --registry file://./registry- go.mod
- switchboard.yaml
- rules/
- basic/
- rule.go
- tests.yaml
- basic/
Look at the rule
A rule is one exported function. switchboard build generates the Wasm wrapper around it, so the package stays plain Go:
package basic
import "github.com/ethndotsh/switchboard/sdk"
func Handle(req sdk.Request) sdk.Action {
if req.Path() == "/blocked" {
return sdk.Deny(403).WithReason("blocked-path")
}
return sdk.Next().SetRequestHeader("x-powered-by", "switchboard")
}Build and test the bundle
build compiles the rule with TinyGo and embeds tests.yaml into the bundle. test runs the bundle against its own behavioral contract:
switchboard build
switchboard testYou can also poke at it interactively with one-off requests:
switchboard eval --method GET --path /blockeddecision: deny
reason: blocked-path
status: 403Deploy it
deploy uploads the bundle to the registry and repoints the prod channel at it, recording an immutable revision:
switchboard deployServe traffic through it
Start the standalone proxy against any upstream (swap in whatever you have listening locally):
switchboard serve --listen :8080 --upstream localhost:3000 \
--registry file://./registry --channel prodcurl -i localhost:8080/blocked # 403 from your rule
curl -i localhost:8080/anything # proxied, with x-powered-by: switchboardChange the rule live
Edit rules/basic/rule.go — say, block another path:
func Handle(req sdk.Request) sdk.Action {
if req.Path() == "/blocked" {
return sdk.Deny(403).WithReason("blocked-path")
}
if req.Path() == "/internal" {
return sdk.Deny(404).WithReason("internal-path")
}
return sdk.Next().SetRequestHeader("x-powered-by", "switchboard")
}switchboard build && switchboard deployWithin the poll interval (2 seconds by default) the running proxy downloads, verifies, tests, and atomically activates the new bundle, with no restart. If you break something:
switchboard rollback --channel prodWhere the defaults came from
switchboard init wrote a switchboard.yaml that every command reads its defaults from, so build, deploy, and friends work with no flags:
name: my-rules
rule: ./rules/basic
dist: ./dist
channel: prod
registry: file://./registry
See the configuration reference for every field.