modo/server/mod.rs
1//! # modo::server
2//!
3//! HTTP server startup, host-based routing, and graceful shutdown.
4//!
5//! Provides:
6//!
7//! - [`Config`] — bind address and shutdown timeout, deserialized from the
8//! `server` YAML section.
9//! - [`http()`] — binds a TCP listener, spawns the server on a background task,
10//! and returns an [`HttpServer`] handle.
11//! - [`HttpServer`] — opaque server handle that implements
12//! [`crate::runtime::Task`] so it composes with the [`crate::run!`] macro for
13//! coordinated graceful shutdown.
14//! - [`HostRouter`] — routes requests to different axum routers by `Host` header;
15//! supports exact matches and single-level wildcard subdomains with an
16//! optional fallback. Implements `Into<axum::Router>` so it plugs directly
17//! into [`http()`].
18//! - [`MatchedHost`] — axum extractor that exposes the subdomain captured by a
19//! wildcard `HostRouter` pattern (plus the pattern itself).
20//!
21//! Trailing slashes are stripped from request paths before routing, so `/app`
22//! and `/app/` resolve to the same handler (the root `/` is preserved).
23//!
24//! ## Quick start
25//!
26//! ```rust,no_run
27//! use modo::{Config, Result};
28//! use modo::axum::Router;
29//!
30//! #[tokio::main]
31//! async fn main() -> Result<()> {
32//! let config: Config = modo::config::load("config/")?;
33//! let app = Router::new();
34//! let server = modo::server::http(app, &config.server).await?;
35//! modo::run!(server).await
36//! }
37//! ```
38
39mod config;
40mod host_router;
41mod http;
42
43pub use config::Config;
44pub use host_router::{HostRouter, MatchedHost};
45pub use http::{HttpServer, http};