A minimal Express.js-like web server for Rust. Provides routing, middleware, request/response objects, error handling, static file serving, and query/body parsing.
Add this crate to your project via cargo install web_rs
use std::convert::Infallible;
use std::sync::Arc;
use hyper::{Body, Request, Response, Method, StatusCode, Server};
use hyper::service::{make_service_fn, service_fn};
use web_rs::{Router, Middleware, serve_static_file, parse_query, parse_json};
#[tokio::main]
async fn main() {
let router: Arc<Router> = Arc::new(Router::new().await);
// Example middleware: logging
router.add_middleware(Arc::new(|req, next| {
Box::pin(async move {
println!("{} {}", req.method(), req.uri().path());
next(req).await
})
})).await;
// Example route: GET /
router.add_route(Method::GET, "/", |req| {
Box::pin(async move {
let query = parse_query(&req);
Response::new(Body::from(format!("Hello, world! Query: {:?}", query)))
})
}).await;
// Example route: POST /echo
router.add_route(Method::POST, "/echo", |req| {
Box::pin(async move {
match parse_json::<serde_json::Value>(req).await {
Ok(json) => Response::new(Body::from(format!("Echo: {}", json))),
Err(resp) => resp,
}
})
}).await;
// Example static file route
router.add_route(Method::GET, "/static", |_| {
Box::pin(async move {
serve_static_file("static/index.html").await
})
}).await;
let make_svc = make_service_fn(move |_| {
let router = router.clone();
async move {
Ok::<_, Infallible>(service_fn(move |req| {
let router = router.clone();
async move { router.handle(req).await }
}))
}
});
let addr = ([127, 0, 0, 1], 3000).into();
let server = Server::bind(&addr).serve(make_svc);
println!("Listening on http://{}", addr);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}- Routing (GET, POST, etc.)
- Middleware support
- Request/response objects
- Error handling
- Static file serving
- Query/body parsing
MIT