Skip to content

Fastly Compute@Edge

Deploy EdgeZero applications to Fastly's Compute@Edge platform using WebAssembly.

Prerequisites

  • Fastly CLI
  • Rust wasm32-wasip1 target: 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.rs

fastly.toml

The Fastly manifest configures your service:

toml
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:

rust
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:

bash
# Using the CLI
edgezero build --adapter fastly

# Or directly with cargo
cargo build -p my-app-adapter-fastly --target wasm32-wasip1 --release

The compiled Wasm binary is placed in target/wasm32-wasip1/release/.

Local Development

Run locally with Viceroy (Fastly's local simulator):

bash
# Using the CLI
edgezero serve --adapter fastly

# Or directly
fastly compute serve --skip-build

This starts a local server at http://127.0.0.1:7676.

Deployment

Deploy to Fastly Compute@Edge:

bash
# Using the CLI
edgezero deploy --adapter fastly

# Or directly
fastly compute deploy

Backends

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.

rust
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:

toml
[adapters.fastly.logging]
endpoint = "stdout"
level = "info"
echo_stdout = true

To initialize logging manually, call init_logger with explicit settings:

rust
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:

toml
[stores.config]
name = "app_config"

For local Viceroy testing, mirror that binding in fastly.toml:

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:

rust
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:

bash
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 contract

Fastly 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

Released under the Apache License 2.0.