Servable: a simple web framework
A tiny, convenient web micro-framework built around htmx, Axum, and Maud. Inspired by the "MASH" stack described here and here.
Features
servable provides abstractions that implement common utilities needed by an http server. \
- response headers and cache-busting utilities
- client device detection (mobile / desktop)
- server-side image optimization (see the
imagefeature below) - ergonomic htmx integration (see
htmx-*features below)
Quick Start
use ;
async
Core Concepts
The Servable trait
The Servable trait is the foundation of this stack.
servable provides implementations for a few common servables:
-
StaticAsset, for static files like CSS, JavaScript, images, or plain bytes:use ; let asset = StaticAsset ; -
Redirect, for simple http redirects:use Redirect; let redirect = new.unwrap; -
HtmlPage, for dynamically-rendered HTML pagesuse ; use html; use Pin; let page = default .with_meta .with_render;HtmlPageautomatically generates a<head>and wraps its rendered html in<html><body>.
ServableRouter
A ServableRouter exposes a collection of Servables under different routes. It implements tower's Service trait, and can be easily be converted into an Axum Router. Construct one as follows:
# use ;
# let home_page = StaticAsset ;
# let about_page = StaticAsset ;
# let stylesheet = StaticAsset ;
# let custom_404_page = StaticAsset ;
let route = new
.add_page
.add_page
.add_page
.with_404; // override default 404
Features
-
image: enable image transformation via query parameters. This makestokioa dependency.
When this is enabled, allStaticAssetswith a valid mimetype can take an optionalt=query parameter.
See theTransformerEnumin this crate's documentation for details.When
imageis enabled, the image below...# use ; let route = new .add_page;...may be accessed as follows:
# Original image GET /image.png # Resize to max 800px on longest side GET /image.png?t= # Crop to a 400x400 square at the center of the image GET /image.png?t= # Chain transformations and transcode GET /image.png?t=;; -
htmx-2.0.8: Include htmx sources in the compiled executable.
Use as follows:# use ServableRouter; # let route = new .add_page .add_page;
Caching and cache-busting
Control caching behavior per servable:
use TimeDelta;
use HtmlPage;
let page = default
.with_ttl
.with_immutable;
Headers are automatically generated:
Cache-Control: public, max-age=3600Cache-Control: immutable, public, max-age=31536000(for immutable assets)