Skip to main content

kerniq_server/
lib.rs

1//! # Kerniq Server
2//!
3//! A lightweight, asynchronous web framework for Rust: the approachability
4//! of Flask on top of Axum, Tower, Hyper and Tokio.
5//!
6//! ```no_run
7//! use kerniq_server::prelude::*;
8//!
9//! #[tokio::main]
10//! async fn main() -> Result<()> {
11//!     App::new()
12//!         .get("/", || async { "Hello from Kerniq" })
13//!         .run("127.0.0.1:3000")
14//!         .await
15//! }
16//! ```
17//!
18//! ## What Kerniq adds, and what it reuses
19//!
20//! Kerniq is a thin ergonomic layer. Routing, extraction and HTTP are
21//! Axum's; middleware is Tower's; the protocol is Hyper's; execution is
22//! Tokio's. Kerniq contributes:
23//!
24//! * the [`App`] builder: Flask-style route registration, typed state,
25//!   configuration, lifecycle (graceful shutdown, background tasks,
26//!   connection and concurrency limits) in one place,
27//! * [`Router`](routing::Router) with prefixes, groups and mounting,
28//! * middleware that applies to every route regardless of declaration order,
29//!   with first-declared-is-outermost ordering,
30//! * one JSON error envelope for application errors, malformed input,
31//!   404/405, timeouts, rate limiting and authentication failures,
32//! * production middleware (logging, request IDs, CORS, compression,
33//!   timeouts, rate limiting, auth extension points, metrics),
34//! * optional OpenAPI, validation and WebSocket support.
35//!
36//! Handlers are plain Axum handlers, and the app converts to an
37//! [`axum::Router`] with [`App::into_axum_router`], so the Axum and Tower
38//! ecosystems stay fully available.
39//!
40//! ## Crate features
41//!
42//! | Feature | Default | Enables |
43//! |---|---|---|
44//! | `json` | ✓ | `Json<T>`, `Created<T>` |
45//! | `tracing` | ✓ | `Logger` middleware |
46//! | `cors` | | `Cors` middleware |
47//! | `compression` | | `Compression` middleware |
48//! | `websocket` | | [`extract::ws`] |
49//! | `openapi` | | `openapi` module (Utoipa + Swagger UI) |
50//! | `validation` | | `ValidatedJson`, `ValidatedQuery` |
51//! | `config-file` | | `ServerConfig::from_file` (TOML) |
52//! | `macros` | | [`authorize`] attribute for role/permission checks |
53//! | `full` | | all of the above |
54//! | `observability` | | [`App::observability`], `observability` module |
55//! | `observability-metrics` | | OpenTelemetry metrics, HTTP metrics |
56//! | `observability-logs` | | JSON / pretty console logs, log export |
57//! | `observability-tracing` | | distributed tracing, W3C propagation |
58//! | `otlp` / `otlp-tls` | | OTLP export to a Collector or backend |
59//! | `prometheus` | | Prometheus scrape endpoint |
60//! | `runtime-metrics` | | Tokio and process metrics |
61//! | `full-observability` | | all observability features except `otlp-tls` |
62
63#![warn(missing_docs)]
64#![cfg_attr(docsrs, feature(doc_cfg))]
65
66mod builder;
67pub mod prelude;
68
69pub use builder::App;
70pub use kerniq_core::{Error, Result};
71
72#[cfg(feature = "macros")]
73pub use kerniq_macros::authorize;
74
75/// Re-export of Axum, for interoperability with Axum handlers, routers and
76/// extractors at a guaranteed-compatible version.
77pub use axum;
78/// Re-export of `http`.
79pub use http;
80/// Re-export of Tower.
81pub use tower;
82
83/// The error model. See [`Error`].
84pub mod error {
85    pub use kerniq_core::error::*;
86}
87
88/// Server configuration. See [`ServerConfig`](config::ServerConfig).
89pub mod config {
90    pub use kerniq_core::config::*;
91}
92
93/// Request extractors.
94pub mod extract {
95    pub use kerniq_http::extractors::*;
96    #[cfg(feature = "websocket")]
97    pub use kerniq_http::ws;
98    pub use kerniq_http::{
99        Body, Bytes, ConnectInfo, Extension, HeaderMap, MatchedPath, OriginalUri, Request, State,
100    };
101    #[cfg(feature = "validation")]
102    pub use kerniq_http::{ValidatedJson, ValidatedQuery, validation_error};
103}
104
105/// Response types.
106pub mod response {
107    pub use kerniq_http::response::*;
108}
109
110/// Routers, groups and method routers.
111pub mod routing {
112    pub use kerniq_routing::path;
113    pub use kerniq_routing::{Group, RouteInfo, Router, methods};
114}
115
116/// Middleware: the composition traits and the built-in middleware.
117pub mod middleware {
118    pub use kerniq_middleware::*;
119    pub use kerniq_routing::{Middleware, MiddlewareStack, TowerLayer};
120}
121
122/// Server lifecycle: shutdown handles, background tasks and runtime helpers.
123pub mod runtime {
124    pub use kerniq_runtime::runtime::in_runtime;
125    pub use kerniq_runtime::{BackgroundTasks, ServeOptions, Shutdown, os_signal};
126}
127
128/// Kerniq Observe: metrics, logs and traces (feature `observability`).
129/// See [`App::observability`].
130#[cfg(feature = "observability")]
131pub mod observability {
132    pub use kerniq_observability::*;
133}
134
135/// OpenAPI documents and Swagger UI (feature `openapi`).
136#[cfg(feature = "openapi")]
137pub mod openapi {
138    pub use kerniq_openapi::*;
139}
140
141/// Compiles every Rust snippet in the README and the guides in `docs/`, so
142/// documentation cannot drift from the API. Pages that need optional
143/// features are only checked when those features are enabled.
144#[cfg(doctest)]
145mod documentation {
146    macro_rules! doc_page {
147        ($name:ident, $path:literal) => {
148            #[doc = include_str!(concat!("../../../", $path))]
149            struct $name;
150        };
151        ($name:ident, $path:literal, $($feature:literal),+) => {
152            #[cfg(all($(feature = $feature),+))]
153            #[doc = include_str!(concat!("../../../", $path))]
154            struct $name;
155        };
156    }
157
158    doc_page!(Readme, "README.md", "json", "tracing");
159    doc_page!(GettingStarted, "docs/getting-started.md", "json");
160    doc_page!(Routing, "docs/routing.md");
161    doc_page!(Handlers, "docs/handlers.md", "json");
162    doc_page!(Extractors, "docs/extractors.md", "json", "validation");
163    doc_page!(StateManagement, "docs/state-management.md", "json");
164    doc_page!(Middleware, "docs/middleware.md", "tracing", "cors");
165    doc_page!(Authorization, "docs/authorization.md", "macros", "json");
166    doc_page!(AxumInterop, "docs/axum-interop.md", "json");
167    doc_page!(Runtime, "docs/runtime.md");
168    doc_page!(Websockets, "docs/websockets.md", "websocket");
169    doc_page!(Configuration, "docs/configuration.md", "config-file");
170    doc_page!(Integrations, "docs/integrations.md");
171    doc_page!(OpenApi, "docs/openapi.md", "openapi", "json");
172    doc_page!(Performance, "docs/performance.md");
173    doc_page!(Architecture, "docs/architecture.md");
174    doc_page!(
175        ObsOverview,
176        "docs/observability/overview.md",
177        "full-observability"
178    );
179    doc_page!(
180        ObsArchitecture,
181        "docs/observability/architecture.md",
182        "full-observability"
183    );
184    doc_page!(
185        ObsPrometheus,
186        "docs/observability/prometheus.md",
187        "full-observability"
188    );
189    doc_page!(ObsOtlp, "docs/observability/otlp.md", "full-observability");
190    doc_page!(
191        ObsLogging,
192        "docs/observability/logging.md",
193        "full-observability"
194    );
195    doc_page!(
196        ObsTracing,
197        "docs/observability/tracing.md",
198        "full-observability"
199    );
200    doc_page!(
201        ObsCustomMetrics,
202        "docs/observability/custom-metrics.md",
203        "full-observability"
204    );
205    doc_page!(
206        ObsGrafana,
207        "docs/observability/grafana.md",
208        "full-observability"
209    );
210    doc_page!(
211        ObsVendors,
212        "docs/observability/vendor-integrations.md",
213        "full-observability"
214    );
215    doc_page!(
216        ObsPerformance,
217        "docs/observability/performance.md",
218        "full-observability"
219    );
220    doc_page!(
221        ObsConfiguration,
222        "docs/observability/configuration.md",
223        "full-observability"
224    );
225    doc_page!(
226        ObsTroubleshooting,
227        "docs/observability/troubleshooting.md",
228        "full-observability"
229    );
230}