Back to all projects

Blueberry

4/29/2025
rust
Blueberry

Blueberry: A High-Performance Rust-Based Web Framework

Technical Overview

Blueberry is an experimental high-performance web framework implemented in Rust, designed to leverage Rust's memory safety guarantees and zero-cost abstractions while providing an ergonomic API for backend development. The framework aims to combine the performance benefits of Rust with a developer-friendly interface that reduces cognitive overhead when building web services.

Core Architecture

The framework is built around two fundamental abstractions that form the basis of the request-response cycle:

pub struct Router {
    pub routes: Vec<Route>,
    middleware: Vec<Middleware>,
    not_found: Route,
}

pub struct Route {
    pub path: String,
    pub method: Method,
    pub handler: RouteHandler,
}

This router implementation utilizes a vector-based route matching system, which provides O(n) lookup complexity in the worst case but optimizes for low memory overhead and cache locality. The router maintains an explicit reference to a not_found handler, eliminating conditional branching in the request processing pipeline for 404 scenarios.

The request model is streamlined to provide efficient access to HTTP primitives:

pub struct Request {
    pub method: Method,
    pub path: String,
    pub headers: HashMap<String, String>,
    pub body: String,
}

This design choice deliberately avoids more complex abstractions found in other frameworks that can introduce unnecessary indirection. By exposing the fundamental HTTP components directly, Blueberry enables developers to interact with the protocol more directly, reducing abstraction overhead.

API Design Philosophy

The API design prioritizes explicit parameter passing over context-based dependency injection patterns. This approach results in handlers with clear signatures that expose their dependencies:

router.add_route("/", Method::GET, |stream, request, headers, params| {
    request.send_message(stream, "HTTP/1.1 200 OK\r\n\r\n");
});

This handler signature provides four essential components:

  1. stream: A direct TCP stream reference for writing response bytes
  2. request: Access to the raw request object
  3. headers: Pre-parsed HTTP headers for efficient access
  4. params: Automatically extracted query parameters

This explicit parameter pattern leverages Rust's ownership model to ensure proper resource management while providing direct access to underlying networking primitives when needed.

Advanced Features

Middleware Pipeline

The middleware implementation uses a functional approach rather than trait-based composition:

pub type Middleware = fn(&mut Request) -> MiddlewareResult;

pub enum MiddlewareResult {
    Continue,
    Terminate(String),
}

This design permits runtime composition of middleware functions without requiring the implementation of traits, enabling a more lightweight approach to extending request processing. Middleware is applied sequentially in registration order, with short-circuiting capabilities through the Terminate variant.

Static Asset Serving

The framework implements optimized static file serving with configurable root directories:

router.load_file_routes(path.unwrap_or(&"./src/pages".to_string()))?;

This implementation utilizes Rust's std::fs module for synchronous file I/O with proper error handling. The file serving system automatically determines appropriate MIME types based on file extensions and implements HTTP cache headers for improved performance.

Performance Characteristics

Blueberry is architected for low overhead request processing:

  1. Zero Heap Allocations in the Hot Path: The request handling pipeline minimizes dynamic memory allocations during the request-response cycle.
  2. Direct Stream Manipulation: By providing access to the TCP stream, developers can implement specialized response patterns without framework overhead.
  3. Minimal Abstraction Tax: The framework avoids complex trait hierarchies and dynamic dispatch where possible, allowing the compiler to optimize critical code paths.

Technical Benefits

Memory Safety Without Garbage Collection

Unlike Node.js, Python, or JVM-based frameworks, Blueberry leverages Rust's ownership model to provide memory safety guarantees without the need for garbage collection. This results in predictable latency profiles and reduced memory overhead, making it particularly suitable for resource-constrained environments.

Concurrent Request Handling

The framework's threading model employs Rust's standard library thread pool implementation, allowing efficient utilization of multi-core systems. Each connection is processed in a separate thread, with careful resource management to prevent thread exhaustion under high load.

Type-Driven Development

Blueberry embraces Rust's strong type system to catch errors at compile time rather than runtime. This approach significantly reduces the class of errors that can occur in production environments and eliminates entire categories of security vulnerabilities common in dynamically typed languages.

Low-Level Control with High-Level Ergonomics

By exposing low-level networking primitives while providing higher-level abstractions, Blueberry gives developers the flexibility to optimize critical paths when necessary without sacrificing productivity for common use cases.

Technical Roadmap

Serialization/Deserialization Pipeline

Future development will include integration with Serde for automatic type-safe parsing of query parameters:

#[derive(Deserialize)]
struct UserQuery {
    id: u64,
    filter: Option<String>,
}

router.add_route("/users", Method::GET, |stream, request, _, params| {
    let query: UserQuery = params.parse()?;
    // Type-safe access to query.id and query.filter
});

Dynamic Content Reloading

Implementation of a file system watcher using the notify crate will enable hot reloading capabilities:

let watcher = FileWatcher::new(path, Duration::from_secs(1));
router.register_watcher(watcher);

This system will utilize an actor-based messaging pattern to safely coordinate file system changes with the request handling pipeline.

Hierarchical Routing

The planned nested router implementation will use a tree-based path matching algorithm to improve route resolution performance:

let v1 = Router::new();
v1.add_route("/users", Method::GET, users_handler);

let v2 = Router::new();
v2.add_route("/users", Method::GET, users_handler_v2);

let main_router = Router::new();
main_router.nest("/v1", v1);
main_router.nest("/v2", v2);

This design will include path parameter extraction with compile-time type checking of route parameters.

Conclusion

Blueberry represents a technically focused approach to web framework design, emphasizing Rust's performance characteristics and safety guarantees while providing an ergonomic development experience. By carefully balancing low-level control with developer productivity, the framework aims to deliver a compelling alternative to both high-level frameworks that sacrifice performance and low-level libraries that sacrifice ergonomics.