pub struct Server<A: ApiSpec> { /* private fields */ }Expand description
A type-safe HTTP server parameterized by an API specification.
The A type parameter is the API type — a tuple of endpoints. The server
ensures at compile time (via Serves) that every endpoint has a handler.
§Example
type API = (
GetEndpoint<path!("hello"), String>,
);
let server = Server::<API>::new((hello_handler,));
server.serve("127.0.0.1:3000".parse().unwrap()).await?;Implementations§
Source§impl<A: ApiSpec> Server<A>
impl<A: ApiSpec> Server<A>
Sourcepub fn new<H: Serves<A>>(handlers: H) -> Self
pub fn new<H: Serves<A>>(handlers: H) -> Self
Create a new server with handlers covering the full API.
Fails to compile if the handler tuple doesn’t match the API type.
Sourcepub fn max_body_size(self, max: usize) -> Self
pub fn max_body_size(self, max: usize) -> Self
Set the maximum request body size in bytes.
Bodies exceeding this limit are rejected with 413 Payload Too Large. Default: 2 MiB (2,097,152 bytes).
Sourcepub fn with_state<T: Clone + Send + Sync + 'static>(self, state: T) -> Self
pub fn with_state<T: Clone + Send + Sync + 'static>(self, state: T) -> Self
Add shared state accessible via State<T> extractors.
Sourcepub fn with_static_files(self, prefix: &str, dir: impl Into<PathBuf>) -> Self
pub fn with_static_files(self, prefix: &str, dir: impl Into<PathBuf>) -> Self
Sourcepub fn with_spa_fallback(self, index_path: impl Into<PathBuf>) -> Self
pub fn with_spa_fallback(self, index_path: impl Into<PathBuf>) -> Self
Serve a file as the fallback for unmatched routes (SPA mode).
When no API route matches, the given file (typically index.html)
is served. This enables client-side routing in single-page apps.
§Example
Server::<API>::new(handlers)
.with_static_files("/static", "./public")
.with_spa_fallback("./public/index.html")
.serve(addr)
.await?;Sourcepub fn with_fallback<S>(self, service: S) -> Self
pub fn with_fallback<S>(self, service: S) -> Self
Set a fallback Tower service for requests that don’t match any typeway route.
This enables embedding an Axum router (or any Tower service) inside
a typeway server — the reverse of into_axum_router().
§Example
let axum_routes = axum::Router::new()
.route("/health", get(|| async { "ok" }));
Server::<API>::new(handlers)
.with_fallback(axum_routes)
.serve(addr)
.await?;Sourcepub fn layer<L>(self, layer: L) -> LayeredServer<L::Service>
pub fn layer<L>(self, layer: L) -> LayeredServer<L::Service>
Apply a Tower middleware layer to the server.
The layer wraps the entire router service. This is the same API
as Axum’s .layer() — any tower::Layer that accepts the router
service type can be used.
§Example
use tower_http::trace::TraceLayer;
use tower_http::cors::CorsLayer;
Server::<API>::new(handlers)
.layer(TraceLayer::new_for_http())
.layer(CorsLayer::permissive())
.serve(addr)
.await?;Sourcepub fn into_service(self) -> RouterService
pub fn into_service(self) -> RouterService
Get the inner RouterService as a Tower service.
Sourcepub fn into_router(self) -> Router
pub fn into_router(self) -> Router
Get the inner router (for integration with other frameworks).
Sourcepub async fn serve(
self,
addr: SocketAddr,
) -> Result<(), Box<dyn Error + Send + Sync>>
pub async fn serve( self, addr: SocketAddr, ) -> Result<(), Box<dyn Error + Send + Sync>>
Start serving HTTP requests on the given address.
Sourcepub async fn serve_with_shutdown(
self,
listener: TcpListener,
shutdown: impl Future<Output = ()> + Send,
) -> Result<(), Box<dyn Error + Send + Sync>>
pub async fn serve_with_shutdown( self, listener: TcpListener, shutdown: impl Future<Output = ()> + Send, ) -> Result<(), Box<dyn Error + Send + Sync>>
Start serving with graceful shutdown.
Supports both HTTP/1.1 and HTTP/2 via automatic protocol detection.
The server stops accepting new connections when the shutdown future
completes. Existing connections are allowed to finish.
§Example
let server = Server::<API>::new(handlers);
let listener = TcpListener::bind("0.0.0.0:3000").await?;
server.serve_with_shutdown(listener, async {
tokio::signal::ctrl_c().await.ok();
}).await?;