pub fn serve<L, M, S, B>(listener: L, make_service: M) -> Serve<L, M, S, B>where
L: Listener,
B: HttpBody + Send + 'static,
B::Data: Send,
B::Error: Into<Box<dyn StdError + Send + Sync>>,
S: Service<Request<Incoming>, Response = Response<B>, Error = Infallible> + Clone + Send + 'static,
S::Future: Send,
M: for<'a> Service<IncomingStream<'a, L>, Error = Infallible, Response = S>,Expand description
Serve the service with the supplied listener.
This implementation provides zero-cost abstraction for shutdown coordination.
When graceful shutdown is not used, there is no runtime overhead - no watch channels
are allocated and no tokio::select! is used.
It supports both HTTP/1 as well as HTTP/2.
This function accepts services wrapped with crate::routing::IntoMakeService or
crate::routing::IntoMakeServiceWithConnectInfo.
For generated Smithy services, use .into_make_service() or
.into_make_service_with_connect_info::<C>(). For services wrapped with
Tower middleware, use IntoMakeService::new(service).
§Error Handling
Note that both make_service and the generated service must have Error = Infallible.
This means:
- Your service factory cannot fail when creating per-connection services
- Your request handlers cannot return errors (use proper HTTP error responses instead)
If you need fallible service creation, consider handling errors within your
make_service implementation and returning a service that produces error responses.
§Examples
Serving a Smithy service with a TCP listener:
use tokio::net::TcpListener;
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
aws_smithy_http_server::serve(listener, app.into_make_service()).await.unwrap();Serving with middleware applied:
use tokio::net::TcpListener;
use tower::Layer;
use tower_http::timeout::TimeoutLayer;
use http::StatusCode;
use std::time::Duration;
use aws_smithy_http_server::routing::IntoMakeService;
let app = /* ... build service ... */;
let app = TimeoutLayer::new(Duration::from_secs(30)).layer(app);
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
aws_smithy_http_server::serve(listener, IntoMakeService::new(app)).await.unwrap();For graceful shutdown:
use tokio::net::TcpListener;
use tokio::signal;
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
aws_smithy_http_server::serve(listener, app.into_make_service())
.with_graceful_shutdown(async {
signal::ctrl_c().await.expect("failed to listen for Ctrl+C");
})
.await
.unwrap();With connection info:
use tokio::net::TcpListener;
use std::net::SocketAddr;
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
aws_smithy_http_server::serve(
listener,
app.into_make_service_with_connect_info::<SocketAddr>()
)
.await
.unwrap();