Establishes the HTTP server layer for the relay binary and the routing pattern all future XRPC endpoints will follow.
What changed#
main.rs— converted to#[tokio::main]; binds a TCP listener and serves with graceful shutdown on SIGTERM/SIGINTapp.rs(new) —AppState+fn app(state) -> Routerfactory; separating router construction from the listener makes handlers testable without a real TCP socketGET /POST /xrpc/:methodcatch-all returns HTTP 501MethodNotImplementedfor any unregistered XRPC NSIDTraceLayer+ permissiveCorsLayerapplied globallyMethodNotImplementedadded toErrorCodewith a PascalCase serde rename to match the AT Protocol XRPC error format
Testing#
cargo test --workspace # 23 tests, 3 new cargo clippy --workspace -- -D warnings cargo fmt --all --check
Manual smoke test: cargo run --bin relay -- --config relay.toml curl -i http://localhost:8080/xrpc/com.atproto.server.createSession expect: HTTP 501, {"error":{"code":"MethodNotImplemented",...}}
Closes MM-71