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!(openapi = "openapi.json", docs_url = "/docs");Vespera scans your src/routes/ folder at compile time, extracts every #[vespera::route] handler and #[derive(Schema)] type, and assembles a complete OpenAPI 3.1 spec — no annotations to maintain, no runtime reflection, no hand-written JSON.
| 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 | #[derive(Schema)] on Rust types | Manual JSON Schema |
| Request validation | Validated<T> extractor → auto 422 | Manual checks in every handler |
| Server startup | .serve("0.0.0.0:3000") one-liner | TcpListener::bind + axum::serve |
| Swagger UI | Built-in | Separate setup |
| Type safety | Compile-time verified | Runtime errors |
| Capability | How |
|---|---|
#[derive(Schema)] → OpenAPI 3.1 | Rust types become JSON Schema at compile time, including serde renames, Option<T>, Vec<T>, SeaORM relations |
Validated<T> extractor + auto-422 | Wraps Json/Form/Query/Path and runs garde::Validate before the handler — rejection is 422 with a canonical JSON envelope |
schema_type! { ... } | Derive request/response DTOs from existing structs (pick / omit / partial / add / multipart / omit_default) with first-class SeaORM relation support |
One-liner .serve(addr) | Extension trait on axum::Router — replaces TcpListener::bind + axum::serve boilerplate |
| JNI / Spring integration | Embed your Axum router inside a Java/Spring app in-process — no TCP, no base64, raw bytes end to end |
| Cron jobs | #[vespera::cron("...")] — auto-discovered like routes, runs via tokio-cron-scheduler |
When embedding Vespera inside a Java/Spring application via JNI, the SmartDispatchModeResolver (default since vespera-bridge 0.2.0) picks the cheapest safe path per request. Measured on a GET /health round-trip through the real JNI boundary (AMD Ryzen 9 9950X, Java 21, Windows 11):
| Request shape | Mode | ns / round-trip |
|---|---|---|
| Small/bodyless + idempotent (GET/HEAD/PUT/DELETE/OPTIONS, ≤ 256 KiB) | DIRECT (pooled direct buffers) | ~2,200 ns |
| Small (≤ 256 KiB) + non-idempotent (POST/PATCH) | SYNC (heap-buffered) | ~3,200 ns |
| Large or unknown-length body | BIDIRECTIONAL_STREAMING | ~24,100 ns |
Binary streaming throughput (64 MiB payload, bidirectional):
| Chunk size | Throughput |
|---|---|
| 16 KiB | ~10,408 MiB/s |
| 64 KiB | ~11,587 MiB/s |
| 256 KiB | ~14,458 MiB/s |
The direct_pooled path completes a tiny /health round-trip in 2,349 ns/op — 1.55× faster than the pre-0.2.0 sync baseline (3,643 ns/op).
src/routes/
├── mod.rs → /
├── users.rs → /users
└── admin/
└── stats.rs → /admin/stats
pub async fn handlers in src/routes/ and annotate them with #[vespera::route].vespera!() macro scans the folder at compile time, discovers every handler, and builds an axum::Router.#[derive(Schema)] are extracted into OpenAPI component schemas automatically.openapi.json and Swagger UI are served at the URLs you configure.Head to Installation to add Vespera to your project in under five minutes.