Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Coming from other frameworks

FastAPI

FastAPIzapline
@app.get("/items/{id}")#[get("/items/{id}")]
def read(id: int, q: str | None = None)async fn read(Path(id): Path<i64>, Query(q): Query<Params>)
Pydantic model#[model] struct (derives serde, JsonSchema and Validate)
Automatic 422 validation errorsValid<Json<T>> → 422 with per-field details
/docs, /openapi.jsonApp::openapi(OpenApi::new("API", "1.0"))
Depends(get_db)Dep<T>, State<T>, custom extractors, Cached<T>
BackgroundTasksBackgroundTasks
HTTPException(404)Err(Error::not_found())
TestClient(app)app.test()
uvicorn --reloadzapline dev
Lifespan eventson_startup / on_shutdown

Spring Boot / ASP.NET Core / NestJS

Conceptzapline
ControllersModules of #[get]/#[post] handlers mounted with .mount((...)), or Routes groups
Beans and services, constructor injectionApp::provide, App::provide_dyn::<dyn Trait>, async provide_with factories, the Dep<T> extractor
application.yml profilesConfig::load(): config/default.toml + config/{profile}.toml + APP__* env vars + .env
Filters, interceptorsMiddleware: App::wrap (pre-routing), App::wrap_route / Routes::wrap (post-routing)
Guards, @PreAuthorize.require_roles([...]), .require_scopes([...]), Guard
Actuator (health, metrics)Health and Metrics plugins
@ScheduledApp::schedule(Schedule::every(..), job)
Exception handlersApp::error_handler
Modules / startersPlugins

axum

zapline will feel familiar. Extractors, IntoResponse and State work the same way. The differences:

  • App::run(addr) gives you a tuned thread-per-core server, with no #[tokio::main] and no serve glue.
  • There's no tower Service/Layer stack. Middleware is async fn(Request, Next) -> Response.
  • State is keyed by type, so you can register many types and the router has no S generic parameter.
  • OpenAPI, validation, DI, configuration, auth, sessions, metrics and health checks are built in.

actix-web

  • Route macros look the same (#[get("/")]), and they also document the route in OpenAPI.
  • Handlers and state are Send, so any Tokio-ecosystem library works.
  • Both use thread-per-core runtimes. zapline uses SO_REUSEPORT listeners and hyper's HTTP stack.