Expand description
Backbone Maintenance Mode — toggleable 503 gate.
When enabled, every request is rejected with HTTP 503 unless the request
path begins with one of the configured allow_paths.
§Consumer-app contract
On a gated request, the response is:
- Status:
503 Service Unavailable - Header:
Retry-After: <seconds>(RFC 7231) - Header:
X-Service-Status: maintenance(machine-readable) - Body (JSON):
{ "status": "maintenance", "message": "...", "retry_after": 300, "severity": "warning", "started_at": "2026-04-25T12:00:00Z", "estimated_end_at": "2026-04-25T13:00:00Z" }
Consumer apps should treat any 503 with X-Service-Status: maintenance as
a maintenance signal and surface a banner or block UI accordingly.
GET /maintenance/status is always reachable (200) for proactive polling.
§Quick start
use std::sync::Arc;
use axum::{Router, routing::{get, post}};
use backbone_maintenance::{
MaintenanceConfig, MaintenanceState,
maintenance_middleware, status_handler, admin_toggle_handler,
};
let cfg = MaintenanceConfig::default();
let state = MaintenanceState::from_config(&cfg);
// Routes for status polling and admin toggle (must remain reachable
// while the gate is on — list `/maintenance` in `allow_paths`).
let maintenance_router = Router::new()
.route("/maintenance/status", get(status_handler))
.route("/maintenance", post(admin_toggle_handler))
.with_state(state.clone());
// Apply the gate as the OUTERMOST middleware so it can short-circuit
// before any downstream layer pays its cost.
Router::new()
.merge(maintenance_router)
// .merge(your_app_routes)
.layer(axum::middleware::from_fn_with_state(
state,
maintenance_middleware,
))Structs§
- Maintenance
Config - Maintenance-mode configuration. Typically deserialized from the consumer
app’s YAML config under a
maintenance:key. - Maintenance
Details - Mutable details surfaced in the 503 body and
/maintenance/status. - Maintenance
Snapshot - Snapshot returned by
/maintenance/statusand used to render 503 bodies. - Maintenance
State - Shared maintenance state. Cloned cheaply via
Arc. Mounted as Axum router state and as middleware state. - Maintenance
Update - Partial update accepted by
POST /maintenance. Any field omitted is left unchanged.estimated_end_at: ""(empty string) clears the field.
Constants§
- MAINTENANCE_
ADMIN_ TOKEN_ ENV - Environment variable name for the admin toggle bearer token. When unset
or empty,
admin_toggle_handlerreturns 501 Not Implemented (closed by default). - X_
SERVICE_ STATUS_ HEADER - Header set on every gated 503 response. Consumers can key off this header to distinguish a maintenance 503 from any other source of 503.
- X_
SERVICE_ STATUS_ MAINTENANCE - Header value for the maintenance status header.
Functions§
- admin_
toggle_ handler POST /maintenance— auth-gated by theMAINTENANCE_ADMIN_TOKENenv var.- maintenance_
middleware - Axum middleware: gate every request unless maintenance is off or the path
matches an
allow_pathsprefix. - status_
handler GET /maintenance/status— always 200. Consumer apps poll this to detect maintenance proactively without getting 503’d.