Skip to main content

Crate backbone_maintenance

Crate backbone_maintenance 

Source
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§

MaintenanceConfig
Maintenance-mode configuration. Typically deserialized from the consumer app’s YAML config under a maintenance: key.
MaintenanceDetails
Mutable details surfaced in the 503 body and /maintenance/status.
MaintenanceSnapshot
Snapshot returned by /maintenance/status and used to render 503 bodies.
MaintenanceState
Shared maintenance state. Cloned cheaply via Arc. Mounted as Axum router state and as middleware state.
MaintenanceUpdate
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_handler returns 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 the MAINTENANCE_ADMIN_TOKEN env var.
maintenance_middleware
Axum middleware: gate every request unless maintenance is off or the path matches an allow_paths prefix.
status_handler
GET /maintenance/status — always 200. Consumer apps poll this to detect maintenance proactively without getting 503’d.