Expand description
A request-scoped configuration snapshot for axum.
use axum::{routing::get, Router};
use dynamic_config_axum::{Config, SnapshotLayer};
use dynamic_config_web_core::sections;
async fn index(
Config(server): Config<Server>,
Config(features): Config<Features>,
) -> String {
// Both came out of one snapshot, taken when the request began.
// `Sections::take` retries if a reload lands mid-read, so these
// two cannot be different generations.
format!("{} {}", server.port, features.cache)
}
let app: Router = Router::new()
.route("/", get(index))
.layer(SnapshotLayer::new(sections![Server, Features]));§What this is for
Server::current() is an atomic load, and calling it in a handler is
correct. Calling it twice, or calling it for two sections, is where a
reload landing mid-request lets one response mix generations.
SnapshotLayer reads every listed section once, before the handler
runs, and stores the result in the request’s extensions. Config<T>
reads it back out. Request extensions are axum’s request scope, so
nothing here is thread-local and nothing has to be undone afterwards.
§What this is not
It does not load configuration, watch files, or own a WatchHandle.
That stays where it already is — in the startup code that calls
init() and holds the handles for the life of the process.
Macros§
- sections
- The sections a request reads, by type.
Structs§
- Config
- One section of this request’s configuration.
- Config
Sections - The sections a request reads, and how to read each one.
- Snapshot
Layer - Takes one snapshot per request and puts it in the request’s extensions.
- Snapshot
Service - The service
SnapshotLayerwraps a router in.
Enums§
- OutOf
Scope - Why a section is not in this request’s snapshot.
- Snapshot
Missing - Why a
Configextractor could not answer.
Functions§
- snapshot
- The snapshot this request began with, for code that has the parts in
hand rather than an extractor — another middleware, or a handler that
takes
Requestwhole.