Skip to main content

Crate rustango

Crate rustango 

Source
Expand description

rustango — a Django-shaped, batteries-included web framework for Rust.

ORM with auto-migrations, auto-admin, multi-tenancy, sessions + JWT + OAuth2/OIDC + HMAC auth, DRF-style serializers + viewsets, signals, caching, media (S3/R2/B2/MinIO), email pipeline, background jobs, scheduled tasks, OpenAPI 3.1 auto-derive, every standard middleware. Postgres + MySQL through the same &Pool API, opt-in via Cargo features.

[dependencies]
rustango = "0.23"

Defaults (["postgres", "admin"]) get you the ORM, migration runner, and auto-admin. Add "tenancy" for the multi-tenant resolver / pools / per-tenant auth pieces, "mysql" for MySQL 8.0+ alongside Postgres, or drop default-features for the bare ORM (no axum, no Tera).

§Quick start

cargo install cargo-rustango
cargo rustango new myblog                 # default: ORM + admin
cargo rustango new myapi --template api   # JSON-only, no admin
cargo rustango new shop --template tenant # multi-tenancy + operator console

Then:

cd myblog
cp .env.example .env                      # set DATABASE_URL
cargo run -- migrate                      # apply bootstrap migrations
cargo run                                 # http://localhost:8080

§Unified manage runner (since v0.16)

Since v0.16 there is one binary that serves HTTP and dispatches manage commands. cargo run starts the server; cargo run -- <verb> runs a CLI command. A scaffolded src/main.rs looks like:

#[rustango::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let _ = dotenvy::dotenv();
    rustango::manage::Cli::new()
        .api(myblog::urls::router())
        .tenancy()                                            // optional, with `tenancy` feature
        .migrations_dir(std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("migrations"))
        .run()
        .await
}

Common manage verbs (every command supports --help):

GroupVerbs
Migrationsmakemigrations, migrate [target], downgrade [N], showmigrations, add-data-op
Scaffoldersstartapp <name>, make:viewset, make:serializer, make:form, make:job, make:notification, make:middleware, make:test
Systemabout, check, check --deploy, version, docs
Tenancycreate-tenant, create-operator, create-user, list-tenants, create-api-key, grant-perm, revoke-perm, audit-cleanup

§Full reference

See the workspace README for the complete feature matrix, ORM cookbook, viewset / serializer recipes, multi-tenancy guide, and production checklist. The examples/cookbook_blog crate ships a runnable multi-tenant blog with one chapter per feature surface.

Re-exports§

pub use sql::Auto;
pub use rustango_macros as macros;

Modules§

access_log
HTTP access log middleware — one tracing event per request with method / path / status / duration / IP. See access_log::AccessLogLayer. HTTP access log middleware — emit one tracing event per request.
account_lockout
Per-account login lockout — defends against credential stuffing. Cache-backed counter + lock flag. See account_lockout::Lockout. Per-account login lockout — defends against credential stuffing / brute-force attacks that bypass per-IP rate limits.
admin
Auto-generated CRUD admin for rustango models.
api_errors
Standardized API error responses. See api_errors::ApiError. Standardized API error responses.
api_keys
Generic API key generation + verification (argon2id-hashed). See api_keys::generate_key / api_keys::verify_key. Generic API key generation and verification.
api_version
API versioning — extract version from header / query / URL prefix. See api_version::VersionStrategy and api_version::ApiVersion. API versioning extractor — read the requested API version from URL, header, or query parameter.
audit
Audit log — single composite-key table that captures every tracked write (insert, update, delete, soft-delete) across every model whose declaration carries #[rustango(audit(...))].
auth_flows
Pre-built auth flows — password reset, email verification, magic-link login. See auth_flows::PasswordReset / auth_flows::EmailVerification. Pre-built auth flows — password reset + email verification.
body_limit
Request body size limit middleware — fast Content-Length rejection returning structured 413 Payload Too Large JSON. Complements axum’s per-extractor DefaultBodyLimit. See body_limit::BodyLimitLayer. Request body size limit middleware.
cache
Pluggable caching layer — cache::Cache trait + cache::NullCache + cache::InMemoryCache. Redis backend behind the cache-redis feature. Pluggable caching layer.
compression
Response compression middleware — gzip + deflate via flate2. Honors Accept-Encoding, skips already-compressed bodies and binary content-types. See compression::CompressionLayer. Response compression middleware — gzip + deflate.
config
Layered TOML configuration (slice 8.3).
content_negotiation
HTTP content negotiation — pick the best response format from the client’s Accept header. See content_negotiation::negotiate. HTTP content negotiation — pick the best response format from the client’s Accept header.
contenttypes
ContentType framework (Django-shape) — runtime handle for “any registered model” used by permissions, generic foreign keys, soft-FK prefetch, audit-history admin panels, etc. Sub-slice F.1 of the v0.15.0 plan. Django-shape ContentType framework — sub-slice F.1 of v0.15.0.
core
Core types for rustango.
cors
CORS middleware — cors::CorsLayer for axum routers. CORS middleware — Cross-Origin Resource Sharing for axum routers.
csp_nonce
Per-request CSP nonce middleware — generates a fresh CSPRNG nonce per request, makes it available via Extension<Nonce>, and substitutes 'nonce-__RUSTANGO_NONCE__' in the CSP header so inline <script nonce="..."> tags pass strict CSP. See csp_nonce::CspNonceLayer. Per-request CSP nonce middleware.
csv
Minimal RFC 4180 CSV writer — zero deps. See csv::CsvWriter. Minimal CSV writer — RFC 4180 compliant, zero deps.
csv_response
axum response wrapper for CSV exports — sets Content-Type + optional Content-Disposition so browsers prompt a “Save as…” download. See csv_response::CsvResponse. axum response wrapper for CSV exports — sets the right Content-Type + an optional Content-Disposition so browsers prompt a “Save as…” download.
distributed_lock
Distributed locks backed by cache::Cache — “only one worker at a time runs this task” with TTL-based crash recovery and token-checked release. See distributed_lock::DistributedLock. Distributed locks backed by Cache.
email
Email backends — email::Mailer trait + console/in-memory/null backends. Email backend layer — pluggable async email sending.
email_jobs
Send email off the request path via the crate::jobs queue. Pairs the email::Mailer trait with the queue’s retry-with- backoff so transient SMTP failures don’t blow up handlers. See email_jobs::register_email_job + email_jobs::dispatch_email. Send email off the request path via the crate::jobs queue.
email_templates
Tera-rendered email helpers — bridge crate::email mailers and the Tera templating engine. Each email = <name>.subject.txt + <name>.txt + optional <name>.html. See email_templates::EmailRenderer. Tera-rendered email helpers — bridge the existing crate::email mailer trait and the Tera templating engine (already a dep on the admin feature).
env
Typed environment variable readers — required / with_default / optional / list / duration_secs / duration_millis. Typed environment variable readers — pydantic-settings / django-environ shape.
etag
ETag middleware — hashes 2xx response bodies, returns 304 when If-None-Match matches. See etag::EtagLayer. ETag middleware — hashes response bodies and serves 304 Not Modified when the client’s If-None-Match matches.
feature_flags
Feature flags / killswitches backed by cache::Cache — boolean killswitch + per-user override + stable percentage rollout. See feature_flags::FeatureFlags. Feature flags / killswitches backed by the Cache trait.
fixtures
Test fixture loader — seed a database from JSON files. See fixtures::Fixture. Test fixture loader — seed a test database from JSON files.
forms
Form parsing, validation, and saving — shared between the auto-admin and user route handlers.
health
Health check endpoints — /health (liveness) + /ready (readiness). See health::health_router. Health check endpoints — /health (liveness) and /ready (readiness).
hmac_auth
HMAC-signed request authentication for service-to-service traffic. AWS-style canonical request signed with SHA-256, replay-bounded by an X-Date tolerance window. See hmac_auth::HmacAuthLayer. HMAC-signed request authentication for service-to-service traffic.
http_client
Opinionated HTTP client — reqwest wrapper with sane timeouts, retry on idempotent verbs / transient failures, default User-Agent. See http_client::HttpClient. Opinionated HTTP client — reqwest wrapper with sane timeouts, exponential-backoff retries on idempotent verbs / transient failures, and a default User-Agent.
i18n
Internationalization (i18n) — translation lookups + Accept-Language negotiation. See i18n::Translator and i18n::negotiate_language. Internationalization (i18n) — translation lookups + Accept-Language negotiation.
idempotency
Idempotency-key middleware (Stripe-shape) — replays a stored successful response when a write request arrives with the same Idempotency-Key. Backed by any cache::Cache. See idempotency::IdempotencyLayer. Idempotency-key middleware (Stripe-shape).
ip_filter
IP allowlist / blocklist middleware. See ip_filter::IpFilterLayer. IP allowlist / blocklist middleware — gate routes by client IP.
jobs
Background job queue with worker pool — async work outside the request lifecycle. Currently in-memory only. See jobs::JobQueue. Background job queue — async work outside the request lifecycle.
jsonapi
JSON:API v1.1 response envelope adapter — wrap a flat serde_json::Value (typical serializer output) into the {"data": {"type", "id", "attributes": {...}}} shape that JSON:API clients expect. See jsonapi::to_resource + jsonapi::to_collection. JSON:API v1.1 response shape adapter.
jwt
Standalone HS256 JWT — sign / verify / decode for magic links, microservice tokens, third-party SSO. See jwt::encode + jwt::decode. Minimal JWT (HS256) — sign, verify, decode.
logging
One-call tracing-subscriber setup. See logging::setup / logging::Setup. Tracing-subscriber setup helpers — the boilerplate every rustango app writes by hand becomes one call.
mailable
Laravel-shape Mailable trait — declare an email type as a struct that owns its template + recipient logic. Pairs with email_templates::EmailRenderer (rendering) and email_jobs (off-request delivery). See mailable::Mailable. Laravel-shape Mailable trait — declare an email type as a struct that owns its own template + recipient logic. Pairs with crate::email_templates::EmailRenderer (template rendering) and crate::email_jobs (off-request delivery).
maintenance
Maintenance-mode middleware — return 503 with Retry-After from a shared atomic flag, so an orchestrator can drain traffic before a deploy / migration without killing in-flight requests. See maintenance::MaintenanceFlag + maintenance::MaintenanceLayer. Maintenance-mode middleware — return 503 with Retry-After from a shared flag, so an orchestrator (or a sidecar) can drain traffic before a deploy / migration without killing in-flight requests.
manage
Unified manage runner — collapses src/main.rs + src/bin/manage.rs boilerplate into one manage::Cli builder. Tenancy variant available when the tenancy feature is on. Behind the manage feature (default-on) which pulls a minimal axum + tokio surface so bare-API projects (no admin) can still use the dispatcher. Unified manage runner — collapses src/main.rs + src/bin/manage.rs boilerplate into one builder so apps stop hand-writing the dispatcher.
media
First-class Media model — Postgres-backed file references with direct-browser upload, CDN-aware URLs, soft delete + orphan purge. See media::Media + media::MediaManager. First-class Media model — a real #[derive(Model)] row that references a file in the crate::storage::Storage layer.
method_override
HTTP method override — rewrite POST → PUT/PATCH/DELETE based on X-HTTP-Method-Override header or _method form field, so HTML forms can drive REST routes. See method_override::MethodOverrideLayer. HTTP method override — rewrite POST → PUT / PATCH / DELETE based on a hidden form field or header.
metrics
Prometheus-format metrics — counters + histograms exposed at /metrics. Pure-Rust, no Prometheus client crate. See metrics::MetricsRegistry + metrics::metrics_router. Prometheus-format metrics — counters + histograms exposed at /metrics.
migrate
Migrations for rustango.
notifications
Multi-channel notifications — fan one notification out to mail / database / log / broadcast channels. See notifications::notify. Multi-channel notifications — fan one notification out to mail / database / log / broadcast channels.
oauth2
OAuth2 / OIDC swiss-knife — social login that works for both pure OAuth2 (GitHub, Discord) and OIDC (Google, Microsoft, Keycloak) providers via the /userinfo endpoint. Per-tenant via oauth2::OAuth2Registry. Optional axum router under oauth2::router (requires the admin feature). OAuth2 / OIDC swiss-knife — one type, every provider.
openapi
OpenAPI 3.1 spec builder + Swagger UI / Redoc viewer routes. Hand-build a spec with openapi::OpenApiSpec and mount it under openapi::router::openapi_router (requires the admin feature). OpenAPI 3.1 spec builder + optional Swagger UI router.
pagination
Pagination helpers — RFC 5988 Link headers + cursor params. See pagination::LinkHeaderBuilder. Pagination helpers — Link headers (RFC 5988) + cursor parameters.
passwords
Generic password hash/verify + strength heuristic. See passwords::hash. Generic password hashing + strength checking.
problem_details
RFC 7807 “Problem Details for HTTP APIs” — standardized error responses with application/problem+json. Sister to api_errors. See problem_details::ProblemDetails. RFC 7807 “Problem Details for HTTP APIs” — standardized error responses with the canonical application/problem+json content type.
query
Query layer for rustango.
rate_limit
Token-bucket rate limiting middleware — rate_limit::RateLimitLayer. Per-IP, per-header, or global. Returns 429 with Retry-After when exhausted. Token-bucket rate limiting middleware for axum routers.
rate_limit_cache
Cache-backed rate limiting middleware — fixed-window counter via the cache::Cache trait. Pair with RedisCache for distributed enforcement across multiple processes / replicas. See rate_limit_cache::CacheRateLimitLayer. Distributed rate limiting via the Cache trait.
real_ip
Real-IP extraction for apps behind a trusted reverse proxy (Cloudflare / nginx / ELB / etc). Parses X-Forwarded-For, X-Real-IP, CF-Connecting-IP, or RFC 7239 Forwarded and stuffs the resolved client IP into request extensions. See real_ip::RealIpLayer. Real-IP extraction middleware for apps behind a trusted reverse proxy.
request_id
Request ID middleware — assign per-request correlation IDs, honor inbound X-Request-Id for end-to-end propagation. See request_id::RequestIdLayer. Request ID middleware — assign a unique ID to every incoming request.
scheduler
In-process scheduled task runner — fire async jobs at fixed intervals. See scheduler::Scheduler. In-process scheduled task runner — fire async jobs at fixed intervals.
secrets
Pluggable secrets backend — secrets::Secrets trait + secrets::EnvSecrets
security_headers
Security headers middleware — HSTS / X-Frame-Options / nosniff / Referrer-Policy / Permissions-Policy / CSP. See security_headers::SecurityHeadersLayer. Security headers middleware — HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Cross-Origin-Opener-Policy, and a Content-Security-Policy builder.
serializer
DRF-style serializer layer — #[derive(Serializer)] + serializer::ModelSerializer. Typed JSON output from model instances with field control and validation. DRF-style serializer layer — typed JSON output from model instances.
server_timing
Server-Timing header middleware — surface per-request stage durations to the browser DevTools “Network” panel. See server_timing::ServerTimingLayer + server_timing::Timings. Server-Timing header middleware — surface per-request stage durations to the browser DevTools “Network → Timing” panel.
sessions
Server-side sessions backed by cache::Cache — opaque cookie ID, server-stored bag of typed values, revocable per-session. See sessions::Session + sessions::SessionStore. Server-side session store backed by crate::cache::Cache.
signals
Django-shape model signals — signals::connect_post_save etc. Receivers register globally per model type and run sequentially. Django-shape model signals — pre_save, post_save, pre_delete, post_delete.
signed_url
Signed URL helpers — HMAC-SHA256 with optional expiry. See signed_url::sign / signed_url::verify. Signed URL helpers — tamper-evident URLs with optional expiry.
soft_delete
Soft-delete query helpers — active_filter / trashed_filter / compose_with_active / soft_delete / restore / purge for any model carrying #[rustango(soft_delete)]. See soft_delete. Soft-delete query helpers.
sql
SQL compilation and execution for rustango.
sse
Broadcast event bus — fan-out for SSE / WebSocket / signal-driven push. See sse::EventBus. Broadcast event bus — fan one message out to every connected subscriber. The foundation for Server-Sent Events (SSE) and other real-time push patterns.
static_files
Static file serving — read files from a directory with sensible Content-Type, Cache-Control, Last-Modified, and 304 support. See static_files::StaticFiles + static_files::static_router. Static file serving — read files from a directory and ship them with sensible Content-Type, Cache-Control, and Last-Modified headers, plus If-Modified-Since 304 support.
storage
File storage backends — storage::Storage trait + LocalStorage + InMemoryStorage. File storage backends — upload, retrieve, delete files via a pluggable trait.
test_client
Test client — fire HTTP requests against an axum::Router in tests without binding a real socket. See test_client::TestClient. Test client — fire HTTP requests against an axum::Router in tests without binding a real socket.
text
Text utilities — slugify, html_escape, truncate. Text utilities — slug generation, HTML escaping, truncation.
totp
TOTP — RFC 6238 time-based one-time passwords for 2FA. See totp::generate / totp::verify / totp::otpauth_url. TOTP — Time-based One-Time Passwords (RFC 6238) for 2FA.
tracing_layer
Per-request tracing span with W3C / OpenTelemetry-conventional field names + traceparent header propagation. Hook tracing_opentelemetry::layer() in your subscriber for free distributed tracing. See tracing_layer::TracingLayer. Per-request tracing span with W3C / OpenTelemetry-conventional field names + traceparent header propagation.
trailing_slash
Trailing-slash redirect middleware — canonicalize URL paths (Django APPEND_SLASH / Rails trailing_slash shape). See trailing_slash::TrailingSlashLayer. Trailing-slash redirect middleware — canonicalize URL paths.
uploads
Multipart file upload helper — wraps axum’s multipart extractor + the storage::Storage trait. See uploads::save_uploads + uploads::UploadConfig. Multipart file upload helper — wraps axum’s multipart extractor + the crate::storage::Storage trait so a file upload handler is a one-liner instead of buffering / size-checking / extension- validating glue.
webhook
Webhook signature verification (HMAC-SHA256). See webhook::verify_signature. Webhook signature verification — HMAC-based, constant-time.
webhook_delivery
Outbound webhook delivery — POSTs HMAC-signed JSON via the background job queue (so retries with exponential backoff are free). See webhook_delivery::WebhookSubscription. Outbound webhook delivery — POSTs an HMAC-signed JSON payload to a subscriber URL via the background job queue.
welcome
First-run welcome page — confidence signal that rustango is wired up. Mount under / while bootstrapping; replace once you have content. See welcome::welcome_router. First-run welcome page — confidence signal that rustango is wired up.
ws
WebSocket handler scaffold — fan-out via sse::EventBus with auto JSON encode/decode + keep-alive ping. See ws::WsHub + ws::ws_handler. WebSocket handler scaffold — fan-out via the SSE [EventBus].

Macros§

embed_migrations
Bake every migration file in a directory into the binary at compile time, for shipping a single-binary distribution. Pair with migrate::migrate_embedded. Bake every *.json migration file in a directory into the binary at compile time. Returns a &'static [(&'static str, &'static str)] of (name, json_content) pairs, lex-sorted by file stem.

Enums§

RustangoError
Unified error type for app-level code. From impls cover every module in the framework so ? Just Works in handlers.

Type Aliases§

RustangoResult
Standard alias.

Attribute Macros§

main
#[rustango::main] — the Django-shape runserver entrypoint. Wraps #[tokio::main] with a default tracing-subscriber boot (env-filter, falling back to info,sqlx=warn). Available behind the runtime feature, which tenancy implies. #[rustango::main] — the Django-shape runserver entrypoint. Wraps #[tokio::main] and a default tracing_subscriber initialisation (env-filter, falling back to info,sqlx=warn) so user main functions are zero-boilerplate:

Derive Macros§

Form
#[derive(Form)] — implements forms::Form so a struct can be parsed from an HTTP form payload with multi-error validation. Re-exported only when the forms feature is on. Derive rustango::forms::FormStruct (slice 8.4B). Generates a parse(&HashMap<String, String>) -> Result<Self, FormError> impl that walks every named field and:
Model
#[derive(Model)] — populates the inventory registry the admin walks, generates objects() / typed columns / insert / delete / save. Derive a Model impl. See crate docs for the supported attributes.
Serializer
#[derive(Serializer)] — implements serializer::ModelSerializer on a struct, generating from_model, a custom serde::Serialize (respecting write_only), and writable_fields. Re-exported when the serializer feature is on. Derive [rustango::serializer::ModelSerializer] for a struct.