Expand description
§Overview
expressjs aims to provide a clean, expressive, and flexible web framework modeled after the ergonomics of Express.js, but with the performance, safety guarantees, and zero-cost abstractions of Rust.
Our goal is simple: no macro magic, no boilerplate, just modular, async-first routing, powerful middleware, and composable handlers.
§Features
- Ergonomic Routing: Express-style routing with
.get(),.post(),.all(), etc. - Robust Middleware System: Layered composition via
app.use(...)enabling powerful request pipelines. - Zero-Macro Abstraction: Minimal
AppandRoutertypes without the need for complex procedural macros. - Fast Route Matching: Powered by an efficient radix tree (
matchthem), supporting parameter extraction (/user/:id). - Memory Efficient: Avoids allocations in the hot path. Uses
SmallVecand a global string interner for path and parameter deduplication. - Extensions & State API: Type-safe, per-request parameter access for seamless state sharing across handlers.
- Comprehensive Built-in Middleware:
cors: Cross-Origin Resource Sharing.auth: Basic, Bearer, and JWT authentication flows.rate_limit: IP-based request throttling.logging: Method, path, and elapsed time tracing.security_headers: Secure defaults (HSTS, X-Frame-Options, etc.).static_serve: Streaming optimization & LRU cache for static files.limit_body: Payload size protections to prevent DoS.normalize_path: Clean routing by normalizing trailing slashes.
§Getting Started
Add expressjs to your Cargo.toml:
[dependencies]
expressjs = "0.1.0"§Basic Example
use expressjs::prelude::*;
#[tokio::main]
async fn main() {
let mut app = express();
// Built-in middleware
app.use_with("/{*p}", LoggingMiddleware);
// or similarly app.use_global(LoggingMiddleware);
// Simple routing
app.get("/", async |_req, res| {
res.send_text("Hello from expressjs!")
});
// JSON response
app.get("/api/ping", async |_req, res| {
res.send_json(&serde_json::json!({ "status": "ok", "message": "pong" }))
});
// Start server
app.listen(3000, || async {
println!("Server listening on http://localhost:3000");
}).await;
}§Modularity & Routing
Just like Express, you can mount routers to organize your controllers:
use expressjs::router::Router;
let mut app = express();
let mut users_router = Router::default();
users_router.get("/", |_req, res| async { res.send_text("List of users") });
users_router.post("/", |_req, res| async { res.send_text("User created") });
users_router.get("/:id", |_req, res| async { res.send_text("User details") });
app.use_router("/users", users_router);§Security & Middleware
A robust set of middlewares is provided out of the box to help secure and optimize your app. For instance, setting up secure headers and rate limiting:
use expressjs::middleware::{rate_limit::*, security_headers::*};
// Restrict to 100 requests per 15 minutes per IP
app.use_global(RateLimit::new(100, std::time::Duration::from_secs(900)));
// Apply secure HTTP headers
app.use_global(SecurityHeaders::default());§Performance
expressjs is built for speed:
- Routes are resolved natively using a specialized Radix tree.
- Minimal to zero heap allocations on a typical incoming HTTP request due to clever internal optimizations.
- Handlers are represented as lightweight function pointers/closures under a uniform
Handlertrait.
§Contributing
We welcome contributions! Whether you’re fixing a bug, proposing a new feature, or improving documentation, please feel free to open an issue or a pull request.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
§License
Distributed under the MIT License. See LICENSE for more information.
Modules§
- prelude
- One-liner imports for
expressjs.
Macros§
- define_
methods - Helper macro that generates convenient fluid HTTP method builder routines on the Router syntax.
- express_
state - Declares a lazily-initialized, globally-shared application state.
Traits§
- Deserialize
- Derive macro for
serde::Deserialize. - Serialize
- Derive macro for
serde::Serialize.
Functions§
- app
- Creates a new Express-style application instance.
- express
- Alias for
app— mirrors theexpress()call familiar from Express.js.
Attribute Macros§
- async_
trait - Derive-able attribute for implementing the
Middlewaretrait on async functions. - main
- Marks an
async fn mainas the Tokio async runtime entry-point.
Derive Macros§
- Deserialize
- Derive macro for
serde::Deserialize. - Serialize
- Derive macro for
serde::Serialize.