What is 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!(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.

Why Vespera?

FeatureVesperaManual Approach
Route registrationAutomatic (file-based)Manual Router::new().route(...)
OpenAPI specGenerated at compile timeHand-written or runtime generation
Schema extraction#[derive(Schema)] on Rust typesManual JSON Schema
Request validationValidated<T> extractor → auto 422Manual checks in every handler
Server startup.serve("0.0.0.0:3000") one-linerTcpListener::bind + axum::serve
Swagger UIBuilt-inSeparate setup
Type safetyCompile-time verifiedRuntime errors

Headline Capabilities

CapabilityHow
#[derive(Schema)] → OpenAPI 3.1Rust types become JSON Schema at compile time, including serde renames, Option<T>, Vec<T>, SeaORM relations
Validated<T> extractor + auto-422Wraps 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 integrationEmbed 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

JNI Performance Numbers

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 shapeModens / 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 bodyBIDIRECTIONAL_STREAMING~24,100 ns

Binary streaming throughput (64 MiB payload, bidirectional):

Chunk sizeThroughput
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/op1.55× faster than the pre-0.2.0 sync baseline (3,643 ns/op).

How It Works

src/routes/
├── mod.rs           → /
├── users.rs         → /users
└── admin/
    └── stats.rs     → /admin/stats
  1. You place pub async fn handlers in src/routes/ and annotate them with #[vespera::route].
  2. The vespera!() macro scans the folder at compile time, discovers every handler, and builds an axum::Router.
  3. Types annotated with #[derive(Schema)] are extracted into OpenAPI component schemas automatically.
  4. The generated openapi.json and Swagger UI are served at the URLs you configure.

Get Started

Head to Installation to add Vespera to your project in under five minutes.

Contents
Edit this page
문의 및 의견 제출
contact@devfive.kr
Copyright © DEVFIVE. All Rights Reserved.
DEVFIVE