Crates.io | micro-web |
lib.rs | micro-web |
version | 0.2.2 |
created_at | 2023-03-27 15:35:33.957852+00 |
updated_at | 2025-09-25 15:12:04.305659+00 |
description | the async micro web framework |
homepage | https://github.com/foldright/micro-http |
repository | https://github.com/foldright/micro-http |
max_upload_size | |
id | 822239 |
size | 146,843 |
A lightweight, modular web framework built on top of micro-http, providing an elegant and efficient way to build web applications in Rust.
Add this to your Cargo.toml
:
[dependencies]
micro-web = "0.1"
tokio = { version = "1", features = ["rt-multi-thread", "net", "io-util", "macros", "sync", "signal"] }
Here's a simple hello world example:
use micro_web::router::{get, Router};
use micro_web::Server;
use micro_web::date::DateServiceDecorator;
/// A simple handler that returns "hello world"
async fn hello_world() -> &'static str {
"hello world"
}
/// Default handler for unmatched handlers (404 responses)
///
/// This handler is called when no other handlers match the incoming request
async fn default_handler() -> &'static str {
"404 not found"
}
#[tokio::main]
async fn main() {
// Create a new router using the builder
let router = Router::builder()
// Add a route that matches GET requests to the root path "/"
// converts our async function into a handler
.route("/", get(hello_world))
// Add middleware that will add date headers to responses
.with_global_decorator(DateServiceDecorator)
.build();
// Configure and start the server
Server::builder()
// Attach our router to handle incoming requests
.router(router)
// Set the address and port to listen on
.bind("127.0.0.1:3000")
// Set a handler for requests that don't match any routes
.default_handler(default_handler)
// Build the server
.build()
.unwrap()
// Start the server and wait for it to finish
.start()
.await;
}
Here's a more complete example showing different request handlers, data extraction, and middleware:
use http::Method;
use micro_web::extract::{Form, Json};
use micro_web::router::filter::header;
use micro_web::router::{get, post, Router};
use micro_web::encoding::encoder::EncodeDecorator;
use micro_web::Server;
use serde::Deserialize;
/// User struct for demonstrating data extraction
#[allow(dead_code)]
#[derive(Deserialize, Debug)]
pub struct User {
name: String,
zip: String,
}
/// Simple GET handler that demonstrates method and optional string extraction
///
/// Example request:
/// ```bash
/// curl http://127.0.0.1:8080/
/// ```
async fn simple_get(method: &Method, str: Option<String>, str2: Option<String>) -> String {
println!("receive body: {}, {}", str.is_some(), str2.is_some());
format!("receive from method: {}\r\n", method)
}
/// Handler that extracts form data into a User struct
///
/// Example request:
/// ```bash
/// curl -v -H "Transfer-Encoding: chunked" \
/// -d "name=hello&zip=world&c=abc" \
/// http://127.0.0.1:8080/
/// ```
async fn simple_handler_form_data(method: &Method, Form(user): Form<User>) -> String {
format!("receive from method: {}, receive use: {:?}\r\n", method, user)
}
/// Handler that extracts JSON data into a User struct
///
/// Example request:
/// ```bash
/// curl -v -H "Transfer-Encoding: chunked" \
/// -H 'Content-Type: application/json' \
/// -d '{"name":"hello","zip":"world"}' \
/// http://127.0.0.1:8080/
/// ```
async fn simple_handler_json_data(method: &Method, Json(user): Json<User>) -> String {
format!("receive from method: {}, receive use: {:?}\r\n", method, user)
}
/// Simple POST handler demonstrating method and optional string extraction
///
/// Example request:
/// ```bash
/// curl -X POST http://127.0.0.1:8080/
/// ```
async fn simple_handler_post(method: &Method, str: Option<String>, str2: Option<String>) -> String {
println!("receive body: {:?}, {:?}", str, str2);
format!("receive from method: {}\r\n", method)
}
/// Another GET handler for a different route
///
/// Example request:
/// ```bash
/// curl http://127.0.0.1:8080/4
/// ```
async fn simple_another_get(method: &Method, str: Option<String>, str2: Option<String>) -> String {
println!("receive body: {:?}, {:?}", str, str2);
format!("receive from method: {}\r\n", method)
}
/// Default handler for unmatched routes
///
/// Example request:
/// ```bash
/// curl http://127.0.0.1:8080/non-existent-path
/// ```
async fn default_handler() -> &'static str {
"404 not found"
}
#[tokio::main]
async fn main() {
// Build router with multiple routes and handlers
let router = Router::builder()
// Basic GET route
.route("/", get(simple_get))
// POST route for form data with content-type filter
.route(
"/",
post(simple_handler_form_data)
.with(header(http::header::CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref())),
)
// POST route for JSON data with content-type filter
.route(
"/",
post(simple_handler_json_data)
.with(header(http::header::CONTENT_TYPE, mime::APPLICATION_JSON.as_ref())),
)
// Default POST route
.route("/", post(simple_handler_post))
// Additional GET route
.route("/4", get(simple_another_get))
// Add response encoding wrapper
.with_global_decorator(EncodeDecorator)
.build();
// Configure and start the server
Server::builder()
.router(router)
.bind("127.0.0.1:8080")
.default_handler(default_handler)
.build()
.unwrap()
.start()
.await;
}
The router provides flexible request routing with support for:
Handlers can be convert from async functions. The framework supports automatic type conversion for both request data extraction and response generation:
// Simple handler returning a string
async fn hello() -> &'static str {
"Hello"
}
// Handler with path parameter
async fn user_info(Path(user_id): Path<String>) -> String {
format!("User ID: {}", user_id)
}
// Handler with JSON request body
async fn create_user(Json(user): Json<User>) -> impl Responder {
// Process user...
StatusCode::CREATED
}
The framework provides type-safe extractors for common data formats:
Path<T>
)Query<T>
)Form<T>
)Json<T>
)HeaderMap
)FromRequest
traitThe framework uses a flexible decorator pattern for middleware:
// Add multiple decorators
router.builder()
.with_global_decorator(DateServiceDecorator) // Adds Date header
.with_global_decorator(CompressionDecorator) // Handles response compression
.build();
Built-in decorators include:
DateServiceDecorator
: Adds date headers to responsesCompressionDecorator
: Handles response compressionDecorator
traitThe framework is built with a modular architecture:
router
: Request routing and filter systemhandler
: Request handler traits and implementationsextract
: Type-safe data extractiondecorator
: Middleware and response transformationresponder
: Response generationBuilt on micro-http, the framework maintains high performance through:
Contributions are welcome! Please feel free to submit a Pull Request.
cargo test
cargo run --example hello_world
This project is licensed under the MIT License or Apache-2.0 License, pick one.
This crate uses unsafe
code in limited, well-documented cases for performance optimization. All unsafe usage is carefully reviewed and tested.
This project is in alpha stage. APIs may change between versions.