- π High Performance - Built on Hyper and Tokio, fully leveraging Rust's asynchronous features.
- π― Type Safe - Complete type inference, catching errors at compile time.
- π Modular Design - Enable features on demand via
features. - π¨ Elegant Macros - Provides concise and intuitive route definition macros.
- π Dependency Injection - Built-in dependency container, supporting automatic component assembly.
- π OpenAPI Support - Seamless integration with
utoipafor automatic API documentation generation. - β
Data Validation - Integrated with
gardefor powerful data validation capabilities. - π WebSocket - Native WebSocket support.
- β Built-in Testing - Powerful TestClient for lightning-fast in-process integration testing.
- π Unified Error Handling - Elegant error handling mechanism.
- π Graceful Shutdown - Signal handling and connection draining.
- π Tower Ecosystem - Compatible with the Tower middleware ecosystem.
cargo add miko --features=fulluse miko::*;
use miko::macros::*;
#[get("/")]
async fn hello() -> &'static str {
"Hello, Miko!"
}
#[miko]
async fn main() {
}After running the program, visit http://localhost:8080.
use miko::{*, macros::*, extractor::{Json, Path, Query}};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct CreateUser {
name: String,
email: String,
}
#[derive(Serialize)]
struct User {
id: u32,
name: String,
email: String,
}
// Using route macros and extractors
#[post("/users")]
async fn create_user(Json(data): Json<CreateUser>) -> Json<User> {
Json(User {
id: 1,
name: data.name,
email: data.email,
})
}
// Path parameters
#[get("/users/{id}")]
async fn get_user(Path(id): Path<u32>) -> Json<User> {
Json(User {
id,
name: "Alice".into(),
email: "alice@example.com".into(),
})
}// Query parameters
#[derive(Debug, Deserialize)]
struct SearchQuery {
q: Option<String>,
page: Option<u32>,
per_page: Option<u32>,
}
#[get("/search")]
async fn search(Query(params): Query<SearchQuery>) -> String {
format!("Searching for: {:?}", params)
}#[tokio::main]
async fn main() {
let router = Router::new()
.post("/users", create_user)
.get("/users/{id}", get_user)
.get("/search", search);
Application::new_(router).run().await.unwrap();
}- Quick Start - 5-minute tutorial
- Basic Concepts - Detailed explanation of core concepts
- Routing System - Route definition and management
- Request Extractors - Extracting request data
- Response Handling - Building various responses
- Error Handling - Unified error handling
- Middleware and Layers - Using middleware
- Dependency Injection - Component management
- WebSocket Support - WebSocket development
- Configuration Management - Application configuration
- OpenAPI Integration - API documentation generation
- Data Validation - Request data validation
- Integration Testing - High-speed integration testing tools
- Advanced Features - Advanced functionalities
Miko has a modular design, allowing you to enable features as needed:
[dependencies]
# By default, core features are enabled (macros, auto-registration, extensions)
miko = "x.x"
# Or enable all features, including OpenAPI and data validation
miko = { version = "x.x", features = ["full"] }
# Or enable only the features you need
miko = { version = "x.x", features = ["utoipa", "validation"] }Available features:
default- Core features (macro+auto+ext), enabled by defaultfull- Enables all features (including external extensions)macro- Enables route macros (#[get],#[post], etc.)auto- Enables automatic route registration and dependency injectionext- Enables extension features (quick CORS, static files, etc.)test- Enables integration testing tools (TestClient)utoipa- Enables OpenAPI documentation generation (automatically re-exports theutoipacrate)validation- Enables data validation (automatically re-exports thegardecrate)
Note: When the utoipa or validation feature is enabled, you don't need to manually add these dependencies to your Cargo.toml. The framework automatically re-exports them:
// After enabling the utoipa feature, use it directly
use miko::{utoipa, OpenApi, ToSchema};
// After enabling the validation feature, use it directly
use miko::{garde, Validate};Define routes with concise macros:
#[get("/users")]
async fn list_users() -> Json<Vec<User>> { /* ... */ }
#[post("/users")]
async fn create_user(Json(data): Json<CreateUser>) -> AppResult<Json<User>> { /* ... */ }
#[put("/users/{id}")]
async fn update_user(Path(id): Path<u32>, Json(data): Json<UpdateUser>) -> AppResult<Json<User>> { /* ... */ }
#[delete("/users/{id}")]
async fn delete_user(Path(id): Path<u32>) -> AppResult<()> { /* ... */ }Use #[component] and #[dep] for dependency injection:
#[component]
impl Database {
async fn new() -> Self {
// Initialize database connection
Self { /* ... */ }
}
}
#[get("/users")]
async fn list_users(#[dep] db: Arc<Database>) -> Json<Vec<User>> {
// Use the injected database instance
Json(vec![])
}Define reusable middleware using #[middleware], supporting argument injection:
#[middleware]
async fn logger(#[config("app.name")] app_name: String) -> AppResult<Resp> {
println!("Request to {}", app_name);
_next.run(_req).await
}
#[get("/")]
#[layer(logger())]
async fn hello() -> &'static str {
"Hello"
}Automatically generate API documentation with inferred params, summary, and description. When utoipa + auto are enabled, AutoPaths can collect macro routes so you do not need to maintain paths(...) manually.
use miko::*;
use miko::openapi::AutoPaths;
#[derive(OpenApi)]
#[openapi(
info(title = "Miko Basic Example API", version = "1.0.0"),
modifiers(&AutoPaths)
)]
struct ApiDoc;
#[derive(Serialize, Deserialize, ToSchema)]
struct User {
id: u32,
name: String,
}
#[get("/users/{id}")]
#[u_tag("User Management")]
#[u_response(status = 200, description = "Success", body = User)]
async fn get_user(
#[path] #[desc("User ID")] id: u32
) -> Json<User> {
// ...
}Use ValidatedJson for automatic validation:
use garde::Validate;
#[derive(Deserialize, Validate)]
struct CreateUser {
#[garde(length(min = 3, max = 50))]
name: String,
#[garde(contains("@"))]
email: String,
}
#[post("/users")]
async fn create_user(
ValidatedJson(data): ValidatedJson<CreateUser>
) -> Json<User> {
// Data has been validated
}The miko/examples/ directory contains a comprehensive all-in-one example:
This example covers most of the framework's core features, including routing, middleware, dependency injection, WebSockets, file uploads, and more. It is highly recommended to check this file to quickly understand how to use Miko.
To run the example:
cargo run --example basic --features fullWe welcome contributions of any kind. For details on how to contribute, please see CONTRIBUTING.md.
- Submit an Issue: GitHub Issues
- Discussion: GitHub Discussions