Module hreq::server [−][src]
Server that handles http requests.
hreq can act as an http server. It supports path based routing to functions acting as handlers, middleware chains and state handling.
Example
use hreq::prelude::*; use hreq::server::Next; async fn start_server() { // Server without a state let mut server = Server::new(); // route requests for /hello/<name> where // "name" is a path parameter that can // be obtained in the request handler. server.at("/hello/:name") // logging middleware .middleware(logging) // dispatch to the handler .get(hello_there); // Listen without TLS let (handle, addr) = server.listen(3000).await.unwrap(); println!("Server listening to: {}", addr); handle.keep_alive().await; } // Middleware logging request and response async fn logging( req: http::Request<Body>, next: Next ) -> http::Response<Body> { println!("Request is: {:?}", req); let res = next.run(req).await.unwrap(); println!("Response is: {:?}", res); res } // Handler of request producing responses. The String is // converted to a 200 response with text/plain. async fn hello_there(req: http::Request<Body>) -> String { format!("Hello {}", req.path_param("name").unwrap()) }
Path parameters
hreq does parsing of path parameters as part of routing.
/literal
matches exactly./:param_name
matches a single path segment delimited by/
and bindsparam_name
parameter./*rest_name
matches the rest of the path and bindsrest_name
parameter.
The bound parameters are available using path_param()
.
Examples
server.at("/user")
matches the path/user
without resulting in a path parameter.server.at("/user/:userId")
matches/user/abc123
with path parameteruserId
set toabc123
.server.at("/user/:userId")
does not math/user/abc123/hello
.server.at("/user/:userId/*whatever")
matches/user/abc123/hello
with path parameteruserId
set toabc123
andwhatever
set tohello
.
use hreq::prelude::*; use hreq::server::Next; async fn start_server() { let mut server = Server::new(); server.at("/hello/:name/*the_rest").get(hello_there); // Listen without TLS let (handle, addr) = server.listen(3000).await.unwrap(); println!("Server listening to: {}", addr); handle.keep_alive().await; } async fn hello_there(req: http::Request<Body>) -> String { println!("All params {:?}", req.path_params()); // prints ["name", "the_rest"] format!("Hello {}: {}", req.path_param("name").unwrap(), req.path_param("the_rest").unwrap()) }
State
Many servers needs to work over some shared mutable state to function.
The server runs in an async runtime (tokio), typically
with multiple threads accepting connections. Therefore the state needs
to be shareable between threads, in rust terms Sync
, as well being
clonable with Clone
.
In practice this often means using a strategy seen in a lot of Rust code:
wrapping the state in Arc<Mutex<State>>
.
Example
use hreq::prelude::*; use std::sync::{Arc, Mutex}; #[derive(Clone)] struct MyCounter(Arc<Mutex<u64>>); async fn start_server() { // Shared state let state = MyCounter(Arc::new(Mutex::new(0))); // Server with a state let mut server = Server::with_state(state); server.at("/do_something") // use stateful middleware/handlers .with_state() .get(my_handler); let (handle, addr) = server.listen(3000).await.unwrap(); handle.keep_alive().await; } async fn my_handler( counter: MyCounter, req: http::Request<Body> ) -> String { let mut lock = counter.0.lock().unwrap(); let req_count = *lock; *lock += 1; format!("Req number: {}", req_count) }
Structs
Next | Type passed to middleware to continue the request chain. |
Reply | Concrete return type from endpoints and middleware. |
Route | A route as obtained by |
Router | Encapsulate chains of |
Server | Server of http requests. |
ServerHandle | Handle to a running server. |
StateRoute | A state route as obtained by |
Static | Serve static files. |
TlsConfig | Configuration builder for |
Traits
Handler | Trait for a request handler that doesn’t use a state. |
Middleware | Trait for middleware that doesn’t use a state. |
ResponseBuilderExt | Extends |
ServerRequestExt | Extends |
StateHandler | Trait for a request handler that use a state. |
StateMiddleware | Trait for middleware that use a state. |