pub struct ApiDefaults { /* private fields */ }Expand description
High-level configurable API defaults built from explicit Axum/Tower primitives.
ApiDefaults is a convenience builder for production-oriented middleware,
not a hidden application runtime. ApiDefaults::production starts with
request IDs, request context, production error envelopes, health routes,
security headers, a Content-Length body limit, and a timeout enabled.
Prometheus metrics and rate limiting are opt-in and only run when configured.
version and environment are stored as labels on this builder for callers
that want to keep one deployment metadata object, but ApiDefaults::apply
does not currently emit those labels to logs, metrics, headers, or health
responses.
use axum::{Router, routing::get};
use nidus_http::{
health::{HealthRegistry, HealthStatus},
middleware::{ApiDefaults, PrometheusMetrics, RequestIdConfig},
};
let metrics = PrometheusMetrics::new();
let health = HealthRegistry::new()
.ready_check_sync("database", || HealthStatus::up());
let router = Router::new().route("/users", get(list_users));
let app = ApiDefaults::production("users-api")
.metrics(metrics.clone())
.health(health)
.request_ids(RequestIdConfig::production())
.apply(router)
.merge(metrics.routes());Implementations§
Source§impl ApiDefaults
impl ApiDefaults
Sourcepub fn production(service_name: impl Into<String>) -> Self
pub fn production(service_name: impl Into<String>) -> Self
Creates production defaults for a service.
Enabled by default:
- request IDs:
RequestIdConfig::production, which requires inbound IDs to be UUID v4 and generates UUID v4 IDs when absent - request context:
request_context_layer - error responses:
ErrorEnvelopeLayer - health routes:
HealthRegistry::newat/health/liveand/health/ready - security headers:
security_headers_layer - body limit:
body_limit_layerwith1 MiB - timeout:
timeout_response_layerwith30s - panic catching:
catch_panic_layerso a panicking handler yields a500envelope instead of aborting the connection
Metrics and rate limiting are disabled unless Self::metrics or
Self::rate_limit is called. The metrics middleware records requests,
but apply does not merge the /metrics route; merge
PrometheusMetrics::routes yourself when you want it exposed.
Sourcepub fn service_name(&self) -> &str
pub fn service_name(&self) -> &str
Returns the service name attached to these defaults.
The current Self::apply implementation keeps this as builder metadata
only; it is not emitted by any default middleware.
Sourcepub fn version(self, version: impl Into<String>) -> Self
pub fn version(self, version: impl Into<String>) -> Self
Sets a service version label.
This is metadata on the builder. Self::apply does not currently
attach the version to metrics, health responses, logs, or response
headers.
Sourcepub fn environment(self, environment: impl Into<String>) -> Self
pub fn environment(self, environment: impl Into<String>) -> Self
Sets an environment label.
This is metadata on the builder. Self::apply does not currently
attach the environment to metrics, health responses, logs, or response
headers.
Sourcepub fn request_ids(self, config: RequestIdConfig) -> Self
pub fn request_ids(self, config: RequestIdConfig) -> Self
Replaces request ID behavior.
Pass RequestIdConfig::development for permissive inbound validation
during local development, or a custom config when you need a different
header name or generator.
Sourcepub fn without_request_ids(self) -> Self
pub fn without_request_ids(self) -> Self
Disables request ID middleware.
Sourcepub fn without_request_context(self) -> Self
pub fn without_request_context(self) -> Self
Disables request context middleware.
Sourcepub fn without_error_envelope(self) -> Self
pub fn without_error_envelope(self) -> Self
Disables production error envelopes.
Sourcepub fn metrics(self, metrics: PrometheusMetrics) -> Self
pub fn metrics(self, metrics: PrometheusMetrics) -> Self
Adds a Prometheus metrics collector.
This installs request lifecycle recording. It does not expose the
collector’s /metrics route; merge PrometheusMetrics::routes into
the router when you want scrape output.
Sourcepub fn without_metrics(self) -> Self
pub fn without_metrics(self) -> Self
Disables metrics middleware.
Sourcepub fn health(self, health: HealthRegistry) -> Self
pub fn health(self, health: HealthRegistry) -> Self
Replaces health routes.
The registry contributes /health/live and /health/ready routes before
middleware layers are applied, so the same default security, timeout, and
body/header handling applies to health responses too.
Sourcepub fn without_health(self) -> Self
pub fn without_health(self) -> Self
Disables health route helpers.
Sourcepub fn rate_limit(self, config: RateLimitConfig) -> Self
pub fn rate_limit(self, config: RateLimitConfig) -> Self
Adds rate limiting.
Sourcepub fn without_rate_limit(self) -> Self
pub fn without_rate_limit(self) -> Self
Disables rate limiting.
Sourcepub fn body_limit(self, max_bytes: u64) -> Self
pub fn body_limit(self, max_bytes: u64) -> Self
Enables or replaces the request body size limit.
The built-in layer checks the declared Content-Length header only. It
rejects declared oversized bodies with 413 Payload Too Large; it does
not count streamed bytes when the header is absent or invalid (e.g.
chunked-transfer clients). For a hard read-time cap across streaming
bodies, also enable Self::streaming_body_limit.
Sourcepub fn streaming_body_limit(self, max_bytes: usize) -> Self
pub fn streaming_body_limit(self, max_bytes: usize) -> Self
Enables a streaming request body limit that counts bytes as they are read.
Unlike Self::body_limit (which inspects only the declared
Content-Length), this wraps the request body and enforces max_bytes
even when Content-Length is absent, closing the chunked-transfer
bypass. The cap is applied as the downstream extractor or handler reads
the body, so a request is rejected only once it actually reads past the
limit. This is opt-in because it wraps every request body; pair it with
Self::body_limit for an early Content-Length rejection plus a hard
streaming cap.
Sourcepub fn without_body_limit(self) -> Self
pub fn without_body_limit(self) -> Self
Disables request body size limiting.
Sourcepub fn security_headers(self) -> Self
pub fn security_headers(self) -> Self
Enables response security headers.
Sourcepub fn without_security_headers(self) -> Self
pub fn without_security_headers(self) -> Self
Disables response security headers.
Sourcepub fn timeout(self, timeout: Duration) -> Self
pub fn timeout(self, timeout: Duration) -> Self
Sets a default request timeout.
Requests whose inner service does not finish before this duration receive
408 Request Timeout with a plain-text request timed out body.
Sourcepub fn without_timeout(self) -> Self
pub fn without_timeout(self) -> Self
Disables timeout middleware.
Sourcepub fn without_catch_panic(self) -> Self
pub fn without_catch_panic(self) -> Self
Disables the panic-catching layer.
With it disabled, a panicking handler may abort the connection instead of
yielding the production 500 envelope. It is enabled by
Self::production.
Sourcepub fn not_found_fallback(self) -> Self
pub fn not_found_fallback(self) -> Self
Enables the default Nidus unmatched-route fallback.
The fallback returns a 404 crate::error::HttpError with code
not_found, allowing the production error-envelope layer to attach
request ID, path, timestamp, and JSON content type consistently.
Sourcepub fn without_not_found_fallback(self) -> Self
pub fn without_not_found_fallback(self) -> Self
Disables the default unmatched-route fallback.
Use this when an application installs its own Axum fallback before
calling Self::apply.
Sourcepub fn apply(self, router: Router) -> Router
pub fn apply(self, router: Router) -> Router
Applies the configured defaults to an existing router.
Health routes are merged first. The effective inbound request order for the default production stack is (outermost first):
security_headers_layerresponse wrappervalidated_request_id_layerrequest_context_layer- metrics, when configured
ErrorEnvelopeLayertimeout_response_layerbody_limit_layerContent-Lengthboundary- rate limiting, when configured
catch_panic_layer, when enabled (innermost, a handler panic is caught and surfaced as a500through every outer layer)- route handlers
body_limit sits inside the request-id, metrics, and error-envelope
layers so an oversized-body 413 is enveloped, metered, and carries a
request id (consistent with how 408 timeouts are observed), rather than
being rejected invisibly at the edge.
Order matters when adding route-specific layers. Layers installed on a
route before calling apply run inside these defaults, so they can see
the validated request ID and enriched crate::context::RequestContext,
and their error responses can be wrapped by the production envelope.
Trait Implementations§
Source§impl Clone for ApiDefaults
impl Clone for ApiDefaults
Source§fn clone(&self) -> ApiDefaults
fn clone(&self) -> ApiDefaults
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more