|
//! # Example server |
|
//! |
|
//! This example shows how to apply middleware from tower-http to a [`Service`] and then run |
|
//! that service using [hyper]. |
|
//! |
|
//! ```rust,no_run |
|
//! use tower_http::{ |
|
//! add_extension::AddExtensionLayer, |
|
//! compression::CompressionLayer, |
|
//! propagate_header::PropagateHeaderLayer, |
|
//! sensitive_headers::SetSensitiveRequestHeadersLayer, |
|
//! set_header::SetResponseHeaderLayer, |
|
//! trace::TraceLayer, |
|
//! validate_request::ValidateRequestHeaderLayer, |
|
//! }; |
|
//! use tower::{ServiceBuilder, service_fn, BoxError}; |
|
//! use http::{Request, Response, header::{HeaderName, CONTENT_TYPE, AUTHORIZATION}}; |
|
//! use std::{sync::Arc, net::SocketAddr, convert::Infallible, iter::once}; |
|
//! use bytes::Bytes; |
|
//! use http_body_util::Full; |
|
//! # struct DatabaseConnectionPool; |
|
//! # impl DatabaseConnectionPool { |
|
//! # fn new() -> DatabaseConnectionPool { DatabaseConnectionPool } |
|
//! # } |
|
//! # fn content_length_from_response<B>(_: &http::Response<B>) -> Option<http::HeaderValue> { None } |
|
//! # async fn update_in_flight_requests_metric(count: usize) {} |
|
//! |
|
//! // Our request handler. This is where we would implement the application logic |
|
//! // for responding to HTTP requests... |
|
//! async fn handler(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> { |
|
//! // ... |
|
//! # todo!() |
|
//! } |
|
//! |
|
//! // Shared state across all request handlers --- in this case, a pool of database connections. |
|
//! struct State { |
|
//! pool: DatabaseConnectionPool, |
|
//! } |
|
//! |
|
//! #[tokio::main] |
|
//! async fn main() { |
|
//! // Construct the shared state. |
|
//! let state = State { |
|
//! pool: DatabaseConnectionPool::new(), |
|
//! }; |
|
//! |
|
//! // Use tower's `ServiceBuilder` API to build a stack of tower middleware |
|
//! // wrapping our request handler. |
|
//! let service = ServiceBuilder::new() |
|
//! // Mark the `Authorization` request header as sensitive so it doesn't show in logs |
|
//! .layer(SetSensitiveRequestHeadersLayer::new(once(AUTHORIZATION))) |
|
//! // High level logging of requests and responses |
|
//! .layer(TraceLayer::new_for_http()) |
|
//! // Share an `Arc<State>` with all requests |
|
//! .layer(AddExtensionLayer::new(Arc::new(state))) |
|
//! // Compress responses |
|
//! .layer(CompressionLayer::new()) |
|
//! // Propagate `X-Request-Id`s from requests to responses |
|
//! .layer(PropagateHeaderLayer::new(HeaderName::from_static("x-request-id"))) |
|
//! // If the response has a known size set the `Content-Length` header |
|
//! .layer(SetResponseHeaderLayer::overriding(CONTENT_TYPE, content_length_from_response)) |
|
//! // Authorize requests using a token |
|
//! .layer(ValidateRequestHeaderLayer::bearer("passwordlol")) |
|
//! // Accept only application/json, application/* and */* in a request's ACCEPT header |
|
//! .layer(ValidateRequestHeaderLayer::accept("application/json")) |
|
//! // Wrap a `Service` in our middleware stack |
|
//! .service_fn(handler); |
|
//! # let mut service = service; |
|
//! # tower::Service::call(&mut service, Request::new(Full::default())); |
|
//! } |
|
//! ``` |
|
//! |
|
//! Keep in mind that while this example uses [hyper], tower-http supports any HTTP |
|
//! client/server implementation that uses the [http] and [http-body] crates. |
Bug Report
The docs have a section "Example server" section which claims to "run that service using hyper."
tower-http/tower-http/src/lib.rs
Lines 12 to 85 in 3f98dc1
However this doesn't seem to use Hyper at all and doesn't actually run any server. There is just hidden code to send a request to the
Servicefrom Rust.Description
It seems that either the wording around the example should be updated or the example should be fixed to actually run a server.
It would be nice to have a minimal server example, as it seems like right now the way to do this is to use a "full featured" framework like axum or warp just to run a tower Service.