Vespera
FastAPI-like developer experience for Rust. Zero-config OpenAPI 3.1 generation for Axum.
// That's it. Swagger UI at /docs, OpenAPI at openapi.json
let app = vespera!;
Why Vespera?
| Feature | Vespera | Manual Approach |
|---|---|---|
| Route registration | Automatic (file-based) | Manual Router::new().route(...) |
| OpenAPI spec | Generated at compile time | Hand-written or runtime generation |
| Schema extraction | From Rust types | Manual JSON Schema |
| Swagger UI | Built-in | Separate setup |
| Type safety | Compile-time verified | Runtime errors |
Quick Start
1. Add Dependencies
[]
= "0.1"
= "0.8"
= { = "1", = ["full"] }
= { = "1", = ["derive"] }
2. Create Route Handler
src/
├── main.rs
└── routes/
└── users.rs
src/routes/users.rs:
use ;
use ;
use Schema;
/// Get user by ID
pub async
/// Create a new user
pub async
3. Setup Main
src/main.rs:
use vespera;
async
4. Run
# Open http://localhost:3000/docs
Core Concepts
File-Based Routing
File structure maps to URL paths automatically:
src/routes/
├── mod.rs → /
├── users.rs → /users
├── posts.rs → /posts
└── admin/
├── mod.rs → /admin
└── stats.rs → /admin/stats
Route Handlers
Handlers must be pub async fn with the #[vespera::route] attribute:
// GET /users (default method)
pub async
// POST /users
pub async
// GET /users/{id}
pub async
// Full options
pub async ...
Schema Derivation
Derive Schema on types used in request/response bodies:
// Serde attributes are respected
Supported Extractors
| Extractor | OpenAPI Mapping |
|---|---|
Path<T> |
Path parameters |
Query<T> |
Query parameters |
Json<T> |
Request body (application/json) |
Form<T> |
Request body (form-urlencoded) |
TypedHeader<T> |
Header parameters |
State<T> |
Ignored (internal) |
Error Handling
pub async
vespera! Macro Reference
let app = vespera!;
Environment Variable Fallbacks
All parameters support environment variable fallbacks:
| Parameter | Environment Variable |
|---|---|
dir |
VESPERA_DIR |
openapi |
VESPERA_OPENAPI |
title |
VESPERA_TITLE |
version |
VESPERA_VERSION |
docs_url |
VESPERA_DOCS_URL |
redoc_url |
VESPERA_REDOC_URL |
servers |
VESPERA_SERVER_URL + VESPERA_SERVER_DESCRIPTION |
Priority: Macro parameter > Environment variable > Default
Advanced Usage
Adding State
let app = vespera!
.with_state;
Adding Middleware
let app = vespera!
.layer
.layer;
Multiple OpenAPI Files
let app = vespera!;
Custom Route Folder
// Scans src/api/ instead of src/routes/
let app = vespera!;
// Or explicitly
let app = vespera!;
Type Mapping
| Rust Type | OpenAPI Schema |
|---|---|
String, &str |
string |
i32, u64, etc. |
integer |
f32, f64 |
number |
bool |
boolean |
Vec<T> |
array with items |
Option<T> |
nullable T |
HashMap<K, V> |
object with additionalProperties |
| Custom struct | $ref to components/schemas |
Project Structure
vespera/
├── crates/
│ ├── vespera/ # Main crate - re-exports everything
│ ├── vespera_core/ # OpenAPI types and abstractions
│ └── vespera_macro/ # Proc-macros (compile-time magic)
└── examples/
└── axum-example/ # Complete example application
Contributing
# Build & test
# Run example
# → http://localhost:3000/docs
See SKILL.md for development guidelines and architecture details.
Comparison
vs. utoipa
- Vespera: Zero-config, file-based routing, compile-time generation
- utoipa: Manual annotations, more control, works with any router
vs. aide
- Vespera: Automatic discovery, built-in Swagger UI
- aide: More flexible, supports multiple doc formats
vs. paperclip
- Vespera: Axum-first, modern OpenAPI 3.1
- paperclip: Actix-focused, OpenAPI 2.0/3.0
License
Apache-2.0
Acknowledgments
Inspired by FastAPI's developer experience and Next.js's file-based routing.