Batteries-Included Features
Floz provides a massive ecosystem for building production backends, eliminating the need to wire up dozens of unmaintained third-party dependencies.
Input Validation
Automatic declarative payload and query string validation based on safe Rust type definitions.
Auth Guards
Macro-driven route protection supporting multiple guards natively in the router with O(1) checking.
Session Management
Built-in Redis-backed stateful sessions with cryptographically secure cookie handling.
JWT & API Keys
Native utility libraries for generating, hashing, and enforcing short-lived and permanent credentials.
Rate Limiting
Declarative, Redis-backed sliding window rate limits wired directly into the #[route] macros.
WebSockets & Channels
Zero-dependency, in-memory WebSocket multiplexing with declarative channel-gated authentication.
Background Workers
Celery-inspired Redis task queue with scheduling, retries, and failure back-offs.
Scheduled Cron Tasks
App-level repeating tasks that run alongside the HTTP server for continuous polling jobs.
File Uploads
Extremely ergonomic native handling of multipart form-data for robust local and object storage.
Testing Utilities
A fluent testing abstraction for integration-level endpoint assertions without needing network ports.
Health & Readiness
Auto-mounted standard endpoints that recursively verify DB and Redis dependencies are alive.
Database Observability
Native exposure of SQLx connection pool lifecycle metrics (idle vs active vs max).
Auto HTTPS / TLS
Effortlessly wire certificate paths to enable HTTPS on the dev server without an Nginx proxy.
Config Profiles
Smart environment cascading that merges .env, .env.development, and .env.production.
Graceful Shutdown
Drain Ntex in-flight HTTP requests and worker processes securely upon receiving a SIGTERM.
Security Tuned
Immediate protection via strict body size limits, CSRF mitigations, and HTTP security headers.
PG LISTEN/NOTIFY
Bridge database channel events natively directly to active users without an intermediary service.
Auto-OpenAPI Docs
Fully compliant Swagger JSON synthesised dynamically from your route handlers at bootup.
Background Task Queue
A Celery-inspired Redis-backed asynchronous queue system with zero-config discovery.
Defining Tasks
#[floz::task(queue = "default", max_retries = 3)]
async fn send_email(to: String, subject: String) -> Result<(), floz::FlozError> {
// Do background work...
Ok(())
}
Dispatching Tasks
// Dispatch immediately
send_email::dispatch("user@example.com".into(), "Welcome".into())
.enqueue()?;
// Schedule with delay
send_email::dispatch("admin@site.com".into(), "Daily Report".into())
.delay(chrono::Duration::hours(24))
.enqueue()?;
Worker Runtime
// Start 4 concurrent worker threads alongside the web server
floz::App::new()
.with_worker(4)
.run(|cfg| {
app::configure(cfg);
})
.await
Note: Requires the worker feature flag and a valid REDIS_URL configured in your environment.
Auth & Sessions
Declarative, zero-overhead macro-driven security maps powered by Redis sessions and JWT token validation.
Declarative Route Protection
Protect a route using `auth` and `permissions` keys in your `#[route(...)]` macro. The global `AuthMiddleware` interprets these rules during request processing with O(1) matching.
#[route(
get: "/admin/dashboard",
auth: "jwt,session",
permissions: ["admin"]
)]
async fn admin_panel(ctx: Context) -> HttpResponse {
// Automatically protected! Only accessible to admins.
let user_id = ctx.req.auth.unwrap().user_id;
// ...
}
Session Injection
Add SessionMiddleware::new() to your App builder to attach Redis-backed user sessions seamlessly.
let session = ctx.session();
session.set("cart_data", "items_xyz").await?;
let items: String = session.get("cart_data").await?.unwrap();
JWT & API Keys
let (token, expiry) = jwt::create_token(
"user-123", "admin", b"secret",
"my-app", "floz", 24, // hours
)?;
let key = api_key::generate_api_key("sk");
let hash = api_key::hash_api_key(&key)?; // bcrypt
PG LISTEN/NOTIFY
Because Floz is strictly coupled with sqlx, you get native access to Postgres' powerful real-time pub/sub event system directly from your handlers.
Streaming DB Changes
Use PgListener to bind a websocket or an SSE (Server-Sent Events) stream natively from the database — no external Redis brokers needed!
use sqlx::postgres::PgListener;
#[route(get: "/live-updates", tag: "Streams")]
async fn live_updates(ctx: Context) -> HttpResponse {
let mut listener = PgListener::connect_with(&ctx.app.db().pool).await.unwrap();
listener.listen("table_updates").await.unwrap();
// Bridge Postgres payloads directly to your active client via Ntex streams!
while let Some(notification) = listener.recv().await.unwrap() {
println!("Live db event: {}", notification.payload());
}
res!("Ok")
}
WebSocket Channels
Zero-dependency, in-memory WebSocket multiplexing. Easily stream events to authorized clients through a single unified connection.
Declarative Channel Security
Use #[channel_gate] to intercept channel subscription requests (e.g. org_123) and validate them inside a handler before they mount. Variables in the pattern are securely mapped to parameters.
#[channel_gate("org_{org_id}")]
async fn check_org_access(ctx: Context, org_id: String) -> bool {
let user = ctx.req.auth.unwrap();
// Only return true if authorized
UserRole::has_role(&ctx.app.db(), user.user_id, &org_id).await
}
Server-Side Publishing
Because Floz manages the connection pool in memory, any route or background task can instantly push messages down the socket without Redis PubSub bottlenecks.
#[route(post: "/orgs/:id/ping")]
async fn send_ping(path: Path<String>, ctx: Context) -> HttpResponse {
let channel = format!("org_{}", path.into_inner());
// Pushes to all connected WebSockets subscribed to this channel
ctx.app.broadcast(&channel, &json!({ "event": "ping" }));
res!("Done")
}
Logging
Daily-rotating log files with stdout mirroring. Auto-initialized by App::run().
// Auto-initialized when logger feature is enabled
floz::logger::init_tracing();
// Output: logs/my-app.log.2026-04-03
// Daily rotation, non-blocking writes
// Override filter via RUST_LOG env var
Utility Macros
| Macro | Description | Example |
|---|---|---|
res!(body) | JSON response (200 or custom status) | res!(body, 201) |
pp!(&data) | Pretty-print in DEV, compact in PROD | pp!(&users).unwrap() |
echo!(...) | Debug log only when ECHO is set | echo!("user {}", id) |
xquery!(sql, ...) | SQLx query with auto-bind | xquery!("SELECT...", id) |
to_json!(row) | Convert sqlx::Row to JSON map | to_json!(row) |
Controller Utilities
JsonResponse
JsonResponse::ok(&users) // 200 (pretty in DEV)
JsonResponse::created(&user) // 201
JsonResponse::no_content() // 204
JsonResponse::bad_request("Invalid") // 400
JsonResponse::not_found("Not found") // 404
PaginationParams
// Auto-extracted from query string
// /users?limit=20&offset=0&order_by=name&search=alice
#[ntex::web::get("/users")]
async fn list(params: web::types::Query<PaginationParams>) -> HttpResponse {
let p = params.into_inner();
// p.limit, p.offset, p.order_by, p.filter, p.search
}
CLI Tool
The floz-cli scaffolds projects and generates domain modules.
$ floz new my-app --template api
$ floz generate model Post title:string body:text
$ floz generate scaffold Post title:string body:text
# Generates: src/app/post/{mod,model,route}.rs
Project Templates
| Template | Features | Use Case |
|---|---|---|
minimal | Single-file server + health | Microservices |
api | Modular src/app/ structure | REST APIs |
saas | Full: auth + workers + Redis | SaaS apps |