Nimble
A simple and elegant Rust web framework inspired by Express, built on Hyper.
Features
- Simple & Intuitive - Express-like route definition style
- Hyper-Powered - Built on a reliable HTTP library
- Zero-Cost Abstractions - Leverages Rust's powerful type system
- Type Safe - Compile-time guarantee of correct types for routes and handlers
- Practical Utilities - Built-in response types for JSON, HTML, file serving, redirects, etc.
- Automatic Static File Serving - Automatically mounts files from the
./staticdirectory - CORS Support - Flexible CORS configuration with simple
.cors()for development and detailed control for production
Quick Start
Add the dependency to your Cargo.toml:
[]
= "2"
= { = "1", = ["full"] }
= { = "1", = ["derive"] } # If handling JSON
Create a simple web application:
use ;
use Deserialize;
async
Routes
Nimble currently supports GET and POST methods, with POST further divided into regular form and JSON types.
use ;
new
.route
.route
.route;
Note: The current version does not support path parameters (e.g.,
/users/:id) or methods likePUTandDELETE.
Response Types
Nimble provides various built-in response types, all implementing the IntoResponse trait:
use ;
// HTML response
Html
// JSON response (requires the type to implement Serialize)
Json
// Plain text response
Text
// Temporary redirect (302)
Redirect
// Permanent redirect (301)
perm
// File response (first parameter: file path, second: force download)
File // Display directly
File // Download as attachment
// Status code only (empty response)
NOT_FOUND
// Content with request headers
Additionally, the following types automatically implement IntoResponse:
&'static strStringVec<u8>()Result<T, E>where bothTandEimplementIntoResponse
Static File Serving
Router::new() automatically scans the ./static folder in your project root and maps all files to routes.
For example, with the following directory structure:
├── static/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── app.js
│ └── images/
| └── logo.png
└── src/
└── main.rs
After starting the application, you can access files via:
http://localhost:3000/css/style.csshttp://localhost:3000/js/app.jshttp://localhost:3000/images/logo.png
File Download
Static file routes support force download via the query parameter ?download=true:
http://localhost:3000/images/logo.png?download=true
CORS Configuration
Nimble provides flexible CORS (Cross-Origin Resource Sharing) support:
Development Mode - One Line Setup
use ;
async
Production Mode - Fine-grained Control
use ;
use Duration;
async
How CORS Works
When a browser makes a cross-origin request, it first sends an OPTIONS preflight request. Nimble automatically handles these and returns the appropriate CORS headers based on your configuration.
// The CORS headers returned for a successful preflight request:
// Access-Control-Allow-Origin: https://myapp.com
// Access-Control-Allow-Methods: GET, POST
// Access-Control-Allow-Headers: Content-Type, Authorization
// Access-Control-Max-Age: 3600
// Access-Control-Allow-Credentials: true
Testing CORS with curl
# Test preflight request
# Test actual request
CORS Configuration Methods
| Method | Description | Example |
|---|---|---|
.cors() |
Quick setup for development, allows all origins | .cors() |
.with_cors(cors) |
Apply custom CORS configuration | .with_cors(my_cors) |
Cors Builder Methods
| Method | Description | Default |
|---|---|---|
.allow_origins(origins) |
Specify allowed origins | None (allows all) |
.allow_methods(methods) |
Specify allowed HTTP methods | ["GET", "POST", "OPTIONS"] |
.allow_headers(headers) |
Specify allowed request headers | ["Content-Type", "Authorization"] |
.allow_credentials(true) |
Allow cookies/auth headers | false |
.max_age(duration) |
Cache preflight response | None |
Debug Logging
Add .debug() to enable request logging:
new
.route
.debug // Enable logging
.run
.await;
Output:
Nimble server running on http://127.0.0.1:3000
192.168.1.100 GET / -> 200 (OK)
192.168.1.100 GET /api/users -> 200 (OK)
192.168.1.100 GET /nonexistent -> 404 (Not Found)
Request Parameters
GET Requests
GET handlers receive a HashMap<String, String> containing query string parameters from the URL.
use HashMap;
async
new.route;
POST Forms
Regular POST handlers also receive a HashMap<String, String>, with data from the application/x-www-form-urlencoded request body.
async
POST JSON
Use post_json to automatically deserialize JSON request bodies into the specified type (must implement Deserialize).
use Deserialize;
async
new.route;
Error Handling
By returning Result<T, E>, you can easily handle errors, where both T and E must implement IntoResponse.
use ;
async
new.route;
License
This project is licensed under:
- MIT
- Apache-2.0
Author: Wang Xiaoyu Email: wxy6987@outlook.com
You are free to choose either license.