25 releases (4 breaking)

Uses new Rust 2024

new 0.5.0 May 5, 2025
0.5.0-rc2 May 4, 2025
0.4.7 Apr 17, 2025
0.3.3 Apr 2, 2025
0.1.3 Feb 26, 2025

#182 in HTTP server

Download history 390/week @ 2025-02-23 333/week @ 2025-03-02 518/week @ 2025-03-09 356/week @ 2025-03-16 294/week @ 2025-03-23 453/week @ 2025-03-30 861/week @ 2025-04-06 208/week @ 2025-04-13 39/week @ 2025-04-20 96/week @ 2025-04-27

1,302 downloads per month

MIT and GPL-3.0-or-later

195KB
3.5K SLoC

Starberry Web Framework

Latest Version Crates.io MIT License

Small, sweet, easy framework for full-stack Rust web applications

📋 Overview

Starberry is a lightweight, intuitive web framework focused on simplicity and productivity. It supports regex-based routing, tree-structured URLs, and integrates seamlessly with the Akari templating system.

Example project

✨ Key Features

  • Simple API: Intuitive request/response handling with minimal boilerplate

  • Full-Stack: Built-in template rendering with Akari templates

  • Flexible Routing: Support for regex patterns, literal URLs, and nested routes

  • Asynchronous: Built with Tokio for efficient async handling

  • Form Handling: Easy processing of form data and file uploads

  • Middleware Support: Create reusable request processing chains

  • Multi-Protocal Support: Starberry is now planning to handle ingoing or outgoing http(s), ws(s), db and other tcp protocals. This will be implemented after 0.7

🚀 Getting Started

Installation

Install starberry bu using

cargo install starberry 

After installing starberry, use

starberry new <Proj_name> 

To create a new project

Quick Start

use starberry::prelude::*; 

#[tokio::main]
async fn main() {
    APP.clone().run().await;
}

pub static APP: SApp = Lazy::new(|| {
    App::new().build()
});

#[lit_url(APP, "/")]
async fn home_route() -> HttpResponse {
    text_response("Hello, world!")
}

Visit your server at http://localhost:3003

Project Structure

project/
├── src/
│   ├── main.rs
│   ├── lib.rs
│   └── ...
└── templates/
    ├── base.html
    ├── index.html
    └── ...

Templates are automatically copied to the dist directory when you run starberry build.

📝 Usage Guide

URL Registration

// Absolute URL
#[url(APP.lit_url("/random/split/something"))]
async fn random_route() -> HttpResponse {
    text_response("A random page")
}

// Relative URL with parent
#[url(reg![&APP, LitUrl("hello")])]
async fn hello() -> HttpResponse {
    text_response("Hello, world!")
}

Method 2: Dynamic Registration

let furl = APP.clone().reg_from(&[LitUrl("flexible"), LitUrl("url")]);
furl.set_method(Arc::new(flexible_access));

URL Pattern Types

Type Description Example
LitUrl(&str) Matches literal path segment LitUrl("users")
RegUrl(&str) Matches regex pattern RegUrl("[0-9]+")
AnyUrl Matches any single path segment AnyUrl
AnyDir Matches any number of path segments AnyDir

Request Handling

#[url(APP.lit_url("/submit"))]
async fn handle_form() -> HttpResponse {
    if request.method() == POST {
        // Form data (application/x-www-form-urlencoded)
        let form = req.form_or_default().await;
        
        // Access form fields
        let name = form.get_or_default("name");
        let age = form.get_or_default("age");
        
        // File uploads
        if let Some(files) = request.files().await {
            if let Some(file) = files.get("file") {
                // Process file
                let file_data = file.data().unwrap();
                // ...
            }
        }
        
        return akari_json!({
            name: form.get_or_default("name"),
            age: form.get_or_default("age")
        });
    }
    
    text_response("Method not allowed").with_status(405)
}

Templating

#[url(APP.lit_url("/template"))]
async fn template() -> HttpResponse {
    akari_template!(
        "template.html",
        title="My Website - Home",
        page_title="Welcome to My Website",
        show_message=true,
        message="Hello, world!",
        items=[1, 2, 3, 4, 5]
    )
}

Template Example:

-[ template "base.html" ]-

-[ block head ]-
<link rel="stylesheet" href="style.css">
<meta name="description" content="My awesome page">
-[ endblock ]-

-[ block content ]-
<div class="container">
    <h2>-[ page_title ]-</h2>
    
    -[ if show_message ]-
        <div class="message">-[ message ]-</div>
    -[ endif ]-
    
    <ul class="items">
        -[ for item items ]-
            <li class="item">-[ item ]-</li>
        -[ endfor ]-
    </ul>
</div>
-[ endblock ]-

Working with Cookies

#[url(APP.lit_url("/cookie"))]
async fn set_cookie() -> HttpResponse {
    text_response("Cookie Set").add_cookie(
        Cookie::new("global_cookie", "something").path("/")
    )
}

JSON Responses

#[url(APP.lit_url("/api/data"))]
async fn api_data() -> HttpResponse {
    akari_json!({
        success: true,
        data: {
            id: 1,
            name: "Example",
            values: [10, 20, 30]
        }
    })
}

Redirects

#[url(APP.lit_url("/redirect"))]
async fn redirect() -> HttpResponse {
    redirect_response("/new-location")
}

📋 Changelog

0.5.0

  • Enable sending requests through a Connection
  • Argumented URL

0.4.x and earlier

  • Request Context holding all contexts of a request
  • Simplified middleware definition pattern & Standard middleware library
  • Added Akari templating support
  • Added cookie manipulation
  • File upload handling
  • Form data processing improvements

🔮 Planned Updates

All planned updates for 0.4 is already finished

  • Standard middleware library (Session)
  • Middleware libraries (OAuth, Surreal)
  • Static file serving
  • Logging
  • Seperate Http from core

📚 Learn More

Learn more about Akari template: https://crates.io/crates/akari

📄 License

MIT License

Dependencies

~14–25MB
~436K SLoC