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

Feature flags

zapline follows "pay only for what you use": anything that pulls in a dependency sits behind a Cargo feature, and a feature you don't use adds no code to your binary and no work to a request.

[dependencies]
zapline = "0.1"                                             # the default features
zapline = { version = "0.1", features = ["ws", "fs"] }      # default features plus WebSockets and static files
zapline = { version = "0.1", features = ["full"] }          # everything
zapline = { version = "0.1", default-features = false, features = ["json", "macros"] }   # a minimal build

Or let the CLI edit Cargo.toml:

zapline add ws fs          # Added features: ws, fs
zapline add --list         # every feature, one line each; * marks the ones you have

When code uses something behind a feature that is off, zapline check and zapline test say which one to add: hint: enable the `ws` feature: zapline add ws (details).

Every feature

The default features are macros, json, query, form, openapi, validate, config and tracing. The full feature enables the defaults plus everything else.

FeatureDefaultEnablesImpliesDependencies it adds
macrosyesThe route attribute macros #[get], #[post], #[put], #[patch], #[delete], #[head], #[options] and #[route], with their OpenAPI arguments (Routing, OpenAPI)zapline-macros (syn, quote, proc-macro2)
jsonyesJson<T> as an extractor and a response, structured error details, Ndjson, Sse::json_data, Message::json and Field::json for WebSockets and uploads, and the test client's .json()serde_json
queryyesThe Query<T> extractorserde_urlencoded
formyesThe Form<T> extractor and the test client's .form()serde_urlencoded
openapiyeszapline::openapi: the OpenApi plugin, Swagger UI, Scalar and Redoc, the builder methods, JsonSchema, and typed clients (client_js, codegen) (OpenAPI, Typed frontends)jsonschemars, zapline-codegen
validateyeszapline::validate: Valid<T> and the 422 error format (Validation)jsonvalidator (with derive)
configyeszapline::config: Config, Secret<T> and App::config (Configuration)toml
tracingyeszapline::telemetry: Telemetry, init() and Trace (Observability). With it, framework logs (failed requests, panics, jobs) go through tracing; without it they go to stderr.tracing, tracing-subscriber (env-filter, fmt, json)
http2fullHTTP/2 support on the server (Server)hyper/http2, hyper-util (http2, server-auto)
tlsfullzapline::tls: TLS with rustls (Server)tokio-rustls (ring, tls12)
http3Experimental. zapline::http3: HTTP/3 over QUIC next to HTTPS, advertised with Alt-Svc (Server)tlsquinn (rustls-ring), h3, h3-quinn
wsfullzapline::ws: WebSockets (WebSockets)tokio-tungstenite (handshake)
fsfullzapline::fs: ServeDir, ServeFile and App::static_files (Static files)mime_guess, tokio-util (io)
multipartfullzapline::multipart: the Multipart extractor (Uploads)multer
compressionfullmiddleware::Compression and CompressionLevel (Hardening)async-compression (gzip, brotli, zstd, deflate, zlib), tokio-util
jwtfullJSON Web Tokens: JwtConfig, Claims, Jwt<C>, JwtAuthenticator, Authenticate::jwt() and App::jwt; key rings with JwtKey (rotate, retire) and App::serve_jwks (Authentication)jsonjsonwebtoken (aws-lc backend, PEM keys)
jwksfullJwks: verify tokens with an identity provider's JWK Set, cached with a TTL, refreshed on unknown kid (rate limited), stale keys kept on errors, OpenID discovery (JWKS)jwthyper-rustls (hyper client, rustls)
cookiesfullzapline::cookies (CookieJar, signed and private jars, Key), zapline::session (SessionLayer, Session) and auth::{Csrf, CsrfToken} (Cookies, sessions & CSRF)jsoncookie (percent-encode, signed, private), getrandom, hmac, sha2 (signed CSRF tokens)
viewsfullzapline::view: Views, App::views, HxRequest, Hx (Views & htmx)minijinja (loader)
passwordfullzapline::auth::password: Argon2id hash and verify (Authentication)argon2, getrandom
mailfullzapline::mail: Mailer, Email, the dev inbox (Email)lettre (SMTP, rustls)
oauthfullzapline::auth::oauth: OAuth (GitHub, Google, custom), App::oauth, OAuthLogin (Social login)jsonhyper-rustls (hyper client, rustls), sha2, getrandom
i18nfullzapline::i18n: I18n (TOML files per language), App::i18n, the Locale extractor, plurals, t(...) in templates (Translations)toml
redisfullzapline::redis: a built-in Redis client (Redis, App::redis), Cache::redis, Live::redis, RateLimit::redis, RedisStore for sessions (Running several instances)json
redis-tlsfullrediss:// URLs for the Redis client: TLS with rustls, the Mozilla root store or your own CA (?ca_file=, Redis::with_ca_pem), and an SNI override (?sni=) (Running several instances)redistokio-rustls, webpki-roots
otlpfullOpenTelemetry trace export over OTLP/HTTP: Telemetry::otlp, or just OTEL_EXPORTER_OTLP_ENDPOINT (Observability)tracing, jsonhyper-rustls (hyper client, rustls)
tzfullIANA time zones (CRON_TZ=Europe/Paris) in cron schedules. UTC and fixed offsets work without it.jiff (system tz database; bundled on Windows)
storagefullzapline::storage: Storage (local directory, memory), signed links, App::storage (File storage)mime_guess, hmac, sha2, getrandom
s3Storage::s3 and S3: S3, R2, MinIO and other S3-compatible services (File storage)storagehyper-rustls (hyper client, rustls)
cachefullzapline::cache: Cache (get_or_set without stampedes), ResponseCache, ETag (Caching)json
postgreszapline::db for Postgres: Database, Db, DbCheck, migrations (Databases)sqlx (postgres, runtime-tokio, migrate, rustls)
sqlitezapline::db for SQLite, including Database::sqlite_memory() for tests (Databases)sqlx (sqlite, runtime-tokio, migrate)
chronofullzapline::chrono (NaiveDate, DateTime<Utc>) with sqlx, serde and OpenAPI support; extract::datetime for datetime-local inputs (Databases)chrono
uuidfullzapline::uuid::Uuid with sqlx, serde and OpenAPI support (Databases)uuid

With postgres or sqlite (and json), zapline::jobs adds durable jobs stored in the same database. With postgres or sqlite, App::admin adds an admin panel for every table. | full | | Every feature above except the database backends (pick postgres and/or sqlite) | all | |

openapi, validate, jwt and cookies turn on json as well, because their error bodies, schemas and session data are JSON.

Always included

Some modules have no feature flag because they add no dependencies:

ModuleWhat it provides
CoreRouting, Path, State, Extension, Bytes and String extractors, responses, errors, the test client, startup/shutdown hooks and plugins
middlewareLogger, Cors, Timeout, DefaultHeaders, CatchPanic, ConcurrencyLimit, NormalizePath, RateLimit, SetRequestId, SecurityHeaders
authBearerToken, BasicAuth, ApiKey, Authenticate, Guard, route policies (JWT and CSRF need their own features)
diDep<T>, Cached<T>, Inject and the provide* methods
tasksBackgroundTasks, App::schedule, App::background
sse, streamServer-Sent Events, StreamBody and BodyStream (Ndjson needs json)
metrics, healthThe Prometheus Metrics plugin and the Health plugin

Choosing features

  • A typical JSON API: the defaults. Add jwt and compression when you need them.
  • A web app with server-rendered pages: cookies (sessions, CSRF) and fs (assets), plus multipart for uploads.
  • Realtime features: ws. Server-Sent Events need no feature.
  • A slim microservice: default-features = false, features = ["json", "macros"] and add config or tracing if you use them. Types and macros behind a missing feature are not compiled, so the compiler tells you when you reach for one, and zapline check names the feature to add.
  • Everything while exploring: full. The examples in the repository (cargo run -p zapline-examples --example openapi) are built with it.

Features are additive and unify across your dependency tree, so one crate enabling full enables it for all. The same applies to the macros: #[get(..)] works without openapi, it just doesn't document anything.

Put #[model] on request and response types and zapline is the only dependency you need: it derives Serialize, Deserialize, JsonSchema (with openapi) and Validate (with validate) through zapline's own re-exports. Writing the derives yourself still works; then add the crates they expand to:

serde = { version = "1", features = ["derive"] }                    # #[derive(Serialize, Deserialize)]
schemars = "1"                                                     # #[derive(JsonSchema)]
validator = { version = "0.21", features = ["derive"] }            # #[derive(Validate)]
tokio = { version = "1", features = ["macros", "rt"] }             # #[tokio::test], in [dev-dependencies]

cargo doc -p zapline --all-features --open builds the API reference with every module visible. The reference on docs.rs is built the same way.