rustapi_core/lib.rs
1//! # RustAPI Core
2//!
3//! Core library providing the foundational types and traits for RustAPI.
4//!
5//! This crate provides the essential building blocks for the RustAPI web framework:
6//!
7//! - **Application Builder**: [`RustApi`] - The main entry point for building web applications
8//! - **Routing**: [`Router`], [`get`], [`post`], [`put`], [`patch`], [`delete`] - HTTP routing primitives
9//! - **Extractors**: [`Json`], [`Query`], [`Path`], [`State`], [`Body`], [`Headers`] - Request data extraction
10//! - **Responses**: [`IntoResponse`], [`Created`], [`NoContent`], [`Html`], [`Redirect`] - Response types
11//! - **Middleware**: [`BodyLimitLayer`], [`RequestIdLayer`], [`TracingLayer`] - Request processing layers
12//! - **Error Handling**: [`ApiError`], [`Result`] - Structured error responses
13//! - **Testing**: `TestClient` - Integration testing without network binding (requires `test-utils` feature)
14//!
15//! ## Quick Start
16//!
17//! ```rust,ignore
18//! use rustapi_core::{RustApi, get, Json};
19//! use serde::Serialize;
20//!
21//! #[derive(Serialize)]
22//! struct Message {
23//! text: String,
24//! }
25//!
26//! async fn hello() -> Json<Message> {
27//! Json(Message { text: "Hello, World!".to_string() })
28//! }
29//!
30//! #[tokio::main]
31//! async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
32//! RustApi::new()
33//! .route("/", get(hello))
34//! .run("127.0.0.1:8080")
35//! .await
36//! }
37//! ```
38//!
39//! ## Feature Flags
40//!
41//! - `metrics` - Enable Prometheus metrics middleware
42//! - `cookies` - Enable cookie parsing extractor
43//! - `test-utils` - Enable testing utilities like `TestClient`
44//! - `swagger-ui` - Enable Swagger UI documentation endpoint
45//! - `http3` - Enable HTTP/3 (QUIC) support
46//! - `http3-dev` - Enable HTTP/3 with self-signed certificate generation
47//!
48//! ## Note
49//!
50//! This crate is typically not used directly. Use `rustapi-rs` instead for the
51//! full framework experience with all features and re-exports.
52
53mod app;
54mod auto_route;
55pub use auto_route::{auto_route_count, collect_auto_routes};
56mod auto_schema;
57pub use auto_schema::apply_auto_schemas;
58#[cfg(feature = "dashboard")]
59pub mod dashboard;
60mod error;
61pub mod events;
62mod extract;
63mod handler;
64pub mod hateoas;
65pub mod health;
66#[cfg(feature = "http3")]
67pub mod http3;
68pub mod interceptor;
69pub(crate) mod json;
70pub mod middleware;
71pub mod multipart;
72pub(crate) mod path_params;
73pub(crate) mod path_validation;
74#[cfg(feature = "replay")]
75pub mod replay;
76mod request;
77mod response;
78mod router;
79mod server;
80pub mod sse;
81pub mod static_files;
82pub mod status;
83pub mod stream;
84pub mod typed_path;
85pub mod validation;
86#[macro_use]
87mod tracing_macros;
88
89/// Private module for macro internals - DO NOT USE DIRECTLY
90///
91/// This module exists **exclusively** to support the `rustapi-macros` crate.
92///
93/// It re-exports:
94/// - `linkme` (for `#[distributed_slice]` attributes generated by our route macros)
95/// - The two distributed slices (`AUTO_ROUTES` and `AUTO_SCHEMAS`)
96/// - Other internal crates needed by the generated code
97///
98/// **Nothing in this module is part of the public API.** It is subject to change
99/// without notice, including the decision to keep using `linkme` or switch to
100/// a different registration mechanism in the future.
101///
102/// External crates should only ever depend on the public surface of `rustapi-core`
103/// (or preferably `rustapi-rs`).
104#[doc(hidden)]
105pub mod __private {
106 /// Re-export of the `linkme` crate.
107 ///
108 /// Used by generated code to emit:
109 /// ```ignore
110 /// #[linkme::distributed_slice(...)]
111 /// #[linkme(crate = ...)]
112 /// ```
113 /// This enables link-time collection of routes and OpenAPI schemas.
114 pub use linkme;
115
116 pub use crate::auto_route::AUTO_ROUTES;
117 pub use crate::auto_schema::AUTO_SCHEMAS;
118
119 pub use rustapi_openapi;
120 pub use rustapi_validate;
121}
122
123// Public API
124pub use app::{ProductionDefaultsConfig, RequestDispatcher, RustApi, RustApiConfig};
125#[cfg(feature = "dashboard")]
126pub use dashboard::{DashboardConfig, DashboardMetrics, DashboardSnapshot};
127pub use error::{get_environment, ApiError, Environment, FieldError, Result};
128pub use events::EventBus;
129#[cfg(feature = "cookies")]
130pub use extract::Cookies;
131pub use extract::{
132 AsyncValidatedJson, Body, BodyStream, ClientIp, CursorPaginate, Extension, FromRequest,
133 FromRequestParts, HeaderValue, Headers, Json, Paginate, Path, Query, State, Typed,
134 ValidatedJson,
135};
136pub use handler::{
137 delete_route, get_route, patch_route, post_route, put_route, Handler, HandlerService, Route,
138 RouteHandler,
139};
140pub use hateoas::{
141 CursorPaginated, Link, LinkOrArray, Linkable, PageInfo, Paginated, Resource, ResourceCollection,
142};
143pub use health::{
144 HealthCheck, HealthCheckBuilder, HealthCheckResult, HealthEndpointConfig, HealthResponse,
145 HealthStatus,
146};
147pub use http::StatusCode;
148#[cfg(feature = "http3")]
149pub use http3::{Http3Config, Http3Server};
150pub use interceptor::{InterceptorChain, RequestInterceptor, ResponseInterceptor};
151#[cfg(feature = "compression")]
152pub use middleware::CompressionLayer;
153pub use middleware::{BodyLimitLayer, RequestId, RequestIdLayer, TracingLayer, DEFAULT_BODY_LIMIT};
154#[cfg(feature = "metrics")]
155pub use middleware::{MetricsLayer, MetricsResponse};
156pub use multipart::{
157 Multipart, MultipartConfig, MultipartField, StreamingMultipart, StreamingMultipartField,
158 UploadedFile,
159};
160pub use path_params::PathParams;
161pub use request::{BodyVariant, Request};
162pub use response::{
163 Body as ResponseBody, Created, Html, IntoResponse, NoContent, Redirect, Response, WithStatus,
164};
165pub use router::{delete, get, patch, post, put, MethodRouter, RouteMatch, Router};
166pub use sse::{sse_from_iter, sse_response, KeepAlive, Sse, SseEvent};
167pub use static_files::{serve_dir, StaticFile, StaticFileConfig};
168pub use stream::{StreamBody, StreamingBody, StreamingConfig};
169pub use typed_path::TypedPath;
170pub use validation::Validatable;