Fastly Compute@Edge
Deploy EdgeZero applications to Fastly's Compute@Edge platform using WebAssembly.
Prerequisites
- Fastly CLI
- Rust
wasm32-wasip1target:rustup target add wasm32-wasip1 - Viceroy for local execution and testing
Project Setup
When scaffolding with edgezero new my-app, the Fastly adapter includes:
crates/my-app-adapter-fastly/
├── Cargo.toml
├── fastly.toml
└── src/
└── main.rsfastly.toml
The Fastly manifest configures your service:
manifest_version = 2
name = "my-app"
language = "rust"
authors = ["you@example.com"]
[local_server]
[local_server.backends]
[local_server.backends."origin"]
url = "https://your-origin.example.com"Entrypoint
The Fastly entrypoint wires the adapter:
use my_app_core::App;
#[fastly::main]
fn main(req: fastly::Request) -> Result<fastly::Response, fastly::Error> {
edgezero_adapter_fastly::run_app::<App>(include_str!("../../../edgezero.toml"), req)
}run_app reads logging and config-store settings from edgezero.toml, builds the app, and injects the configured Fastly Config Store into request extensions automatically.
The low-level dispatch() helper remains available only for fully manual wiring and does not inject config-store metadata. Prefer run_app or dispatch_with_config for normal use. dispatch_with_config_handle exists for advanced/manual cases where you already have a prepared ConfigStoreHandle.
Building
Build for Fastly's Wasm target:
# Using the CLI
edgezero build --adapter fastly
# Or directly with cargo
cargo build -p my-app-adapter-fastly --target wasm32-wasip1 --releaseThe compiled Wasm binary is placed in target/wasm32-wasip1/release/.
Local Development
Run locally with Viceroy (Fastly's local simulator):
# Using the CLI
edgezero serve --adapter fastly
# Or directly
fastly compute serve --skip-buildThis starts a local server at http://127.0.0.1:7676.
Deployment
Deploy to Fastly Compute@Edge:
# Using the CLI
edgezero deploy --adapter fastly
# Or directly
fastly compute deployBackends
EdgeZero's Fastly proxy client uses dynamic backends derived from the target URI (host + scheme). You do not need to predeclare backends in fastly.toml for EdgeZero proxying.
use edgezero_adapter_fastly::FastlyProxyClient;
use edgezero_core::proxy::ProxyService;
let client = FastlyProxyClient;
let response = ProxyService::new(client).forward(request).await?;Logging
Fastly uses endpoint-based logging. Configure logging in edgezero.toml:
[adapters.fastly.logging]
endpoint = "stdout"
level = "info"
echo_stdout = trueTo initialize logging manually, call init_logger with explicit settings:
use edgezero_adapter_fastly::init_logger;
use log::LevelFilter;
fn main() {
init_logger("stdout", LevelFilter::Info, true).expect("init logger");
}Logging status
Fastly logging is wired when you call init_logger (or run_app); otherwise no logger is installed.
Config Store
Fastly uses a native Config Store resource link for runtime configuration. Declare the logical store name in edgezero.toml:
[stores.config]
name = "app_config"For local Viceroy testing, mirror that binding in fastly.toml:
[local_server.config_stores.app_config]
format = "inline-toml"
[local_server.config_stores.app_config.contents]
greeting = "hello from config store"Handlers can then read values through ctx.config_store(). If the configured store link is missing, the adapter logs a warning and continues without injecting a config-store handle.
Context Access
Access Fastly-specific APIs via the request context extensions:
use edgezero_core::context::RequestContext;
use edgezero_adapter_fastly::FastlyRequestContext;
async fn handler(ctx: RequestContext) -> Result<Response, EdgeError> {
// Access Fastly context from extensions
if let Some(fastly_ctx) = FastlyRequestContext::get(ctx.request()) {
let client_ip = fastly_ctx.client_ip;
// ...
}
// ...
}Streaming
Fastly supports native streaming via stream_to_client. The adapter automatically converts Body::stream to Fastly's streaming APIs.
See the Streaming guide for examples and patterns.
Testing
Run contract tests for the Fastly adapter:
cargo install viceroy --locked
export CARGO_TARGET_WASM32_WASIP1_RUNNER="viceroy run"
# Run tests
cargo test -p edgezero-adapter-fastly --features fastly --target wasm32-wasip1 --test contractFastly SDK-linked Wasm binaries require Viceroy for execution; plain Wasmtime does not provide the fastly_* host imports needed by the adapter tests.
Local Execution
If Viceroy reports native certificate or keychain errors on macOS, use --no-run locally and rely on Linux CI for execution.
Manifest Configuration
Configure the Fastly adapter in edgezero.toml. See Configuration for the full manifest reference.
Next Steps
- Learn about Cloudflare Workers as an alternative deployment target
- Explore Configuration for manifest details