sunweb 0.4.0

A small lightweight Rust web framework.
Documentation

Project: sunweb

Sunnickel | 04.10.2025


A lightweight, fast, and flexible HTTP/HTTPS web server written in Rust with domain routing, middleware support, and TLS capabilities.


Features

  • Macro-driven routing — define routes with #[get], #[post], #[put], #[delete], #[patch], #[head], #[options]
  • HTTP & HTTPS — built-in TLS via rustls, automatic HTTP → HTTPS redirect
  • Middleware — request, response, and request+response middleware, scoped by path prefix
  • Static file serving#[static_files("/assets", "./public")]
  • Reverse proxy#[proxy("/api", "http://localhost:3000")]
  • Custom error pages#[error_page(404)]
  • Templating (optional feature) — lightweight {{ var }}, {% if %}, {% for %} engine
  • Colored logging — built-in Logger with per-level ANSI colors
  • Cookie support — full cookie jar on request and response
  • Keep-alive — persistent connections handled automatically

Installation

[dependencies]

sunweb = "0.3.0"

With templating:

[dependencies]

sunweb = { version = "0.3.0", features = ["templating"] }


Quick Start

use sunweb::{App, get, HTTPRequest, Response};
use log::LevelFilter;

#[derive(App)]
struct MyApp;

#[get("/")]
async fn index(req: HTTPRequest) -> Response {
    Response::ok()
        .set_html()
        .set_body_string("Hello from SunWeb!".into())
}

fn main() {
    sunweb::Logger::init(LevelFilter::Info);

    MyApp::builder()
        .http("0.0.0.0:8080")
        .run();
}

HTTPS

MyApp::builder()
    .http("0.0.0.0:8080")       // redirects to HTTPS automatically
    .https("0.0.0.0:8443")
    .cert("key.pem", "cert.pem")
    .domain("example.com")
    .run();

Routing

use sunweb::{get, post, delete, HTTPRequest, Response, JsonResponse, TextResponse};

#[get("/users")]
async fn list_users(req: HTTPRequest) -> JsonResponse {
    JsonResponse::ok(r#"{"users": []}"#)
}

#[post("/users")]
async fn create_user(req: HTTPRequest) -> JsonResponse {
    let name = req.form("name").unwrap_or("unknown");
    JsonResponse::ok(format!(r#"{{"name": "{}"}}"#, name))
}

#[delete("/users")]
async fn delete_user(req: HTTPRequest) -> Response {
    Response::no_content()
}

Static Files

use sunweb::static_files;

#[static_files("/assets", "./public")]
struct Assets;

Reverse Proxy

use sunweb::proxy;

#[proxy("/api", "http://localhost:3000")]
struct ApiProxy;

Middleware

use sunweb::{middleware, HTTPRequest, Response};

// Applies to all routes
#[middleware]
fn log_requests(req: &mut HTTPRequest) {
    println!("{} {}", req.method(), req.path());
}

// Scoped to /admin/*
#[middleware("/admin")]
fn require_auth(req: &mut HTTPRequest) {
    // reject unauthenticated requests
}

// Response middleware
#[middleware]
fn add_cors(res: &mut Response) {
    res.set_cors_origin("*");
}

Error Pages

use sunweb::{error_page, HTTPRequest, HtmlResponse, TextResponse};

#[error_page(404)]
fn not_found(req: HTTPRequest) -> HtmlResponse {
    HtmlResponse::ok("404 — Page Not Found")
}

#[error_page(500)]
fn server_error(req: HTTPRequest) -> HtmlResponse {
    HtmlResponse::ok("500 — Something went wrong")
}

Templating (feature = "templating")

use sunweb::{get, render, HTTPRequest, Response, Context, Value};

#[get("/")]
async fn index(req: HTTPRequest) -> Response {
    let mut ctx = Context::new();
    ctx.insert("title".into(), Value::from("Home"));
    ctx.insert("logged_in".into(), Value::Bool(true));
    ctx.insert("users".into(), Value::List(vec![
        [("user.name".into(), Value::from("Alice"))].into(),
        [("user.name".into(), Value::from("Bob"))].into(),
    ]));
    render!("index.html", ctx)
}

Template syntax:

Syntax Description
{{ name }} Variable interpolation
{% if condition %}{% endif %} Conditional block
{% for item in list %}{% endfor %} Loop

Logging

use sunweb::Logger;
use log::LevelFilter;

Logger::init(LevelFilter::Info);

log::info!("Server starting");
log::warn!("Something looks off");
log::error!("Something broke");
Level Color
error Red
warn Yellow
info Blue
debug Green
trace Dimmed

Response Types

Type Content-Type
HtmlResponse text/html
JsonResponse application/json
PlainTextResponse text/plain
ImageResponse image/*
RedirectResponse — sets Location header
NoContentResponse 204 No Content
Response fully manual

Workspace Structure

sunweb/
├── sunweb/              # Main crate — public API & re-exports
├── sunweb_core/         # HTTP types, server runtime, request/response
├── sunweb_macros/       # Procedural macros (#[get], #[middleware], etc.)
├── sunweb_templating/   # Optional templating engine
└── example_app/         # Usage examples (not published)

License

MIT — see LICENSE for details.

Contributing

Pull requests are welcome.

Author

Sunnickel

Links

AI Assistance

This project's documentation, including this README.md file, has been created with the assistance of AI.

Specifically, AI was used for:

  • Documentation generation
  • Content creation for this README.md

All content has been reviewed and edited to ensure accuracy and clarity. While AI tools were utilized to accelerate the writing process, all information has been manually checked for correctness.