expressjs 0.9.2

Fast, unopinionated, minimalist web framework for Rust, similar to Express.js
Documentation

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 App and Router types 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 SmallVec and 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 Handler trait.

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.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.