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 - Wasmtime or Viceroy for local 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 edgezero_adapter_fastly::dispatch;
use edgezero_core::app::Hooks;
use my_app_core::App;
#[fastly::main]
fn main(req: fastly::Request) -> Result<fastly::Response, fastly::Error> {
let app = App::build_app();
dispatch(&app, req)
}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.
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:
# Set up the Wasm runner
export CARGO_TARGET_WASM32_WASIP1_RUNNER="wasmtime run --dir=."
# Run tests
cargo test -p edgezero-adapter-fastly --features fastly --target wasm32-wasip1Viceroy Issues
If Viceroy reports keychain access errors on macOS, use Wasmtime as the test runner instead.
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