11# VESPERA PROJECT KNOWLEDGE BASE
22
3- ** Generated:** 2026-02-04
3+ ** Generated:** 2026-03-21
44** Branch:** main
55
66## OVERVIEW
77
88Vespera is a fully automated OpenAPI 3.1 engine for Axum - delivers FastAPI-like DX to Rust. Zero-config route discovery via compile-time macro scanning.
99
10+ Also provides in-process dispatch (` vespera_inprocess ` crate) and JNI integration (` vespera_jni ` crate) for embedding Rust axum apps inside Java/Spring applications without HTTP overhead.
11+
1012## STRUCTURE
1113
1214```
1315vespera/
1416├── crates/
15- │ ├── vespera/ # Public API - re-exports everything (+ chrono re-export)
16- │ ├── vespera_core/ # OpenAPI types, route/schema abstractions
17- │ └── vespera_macro/ # Proc-macros (main logic lives here)
18- └── examples/axum-example/ # Demo app with route patterns
17+ │ ├── vespera/ # Public API - re-exports everything
18+ │ │ └── src/lib.rs # Core re-exports (no transport deps)
19+ │ ├── vespera_core/ # OpenAPI types, route/schema abstractions
20+ │ ├── vespera_macro/ # Proc-macros (main logic lives here)
21+ │ ├── vespera_inprocess/ # In-process dispatch (transport-agnostic)
22+ │ │ └── src/lib.rs # dispatch(), register_app(), dispatch_from_json()
23+ │ └── vespera_jni/ # JNI bridge (depends on vespera_inprocess)
24+ │ └── src/lib.rs # RUNTIME, jni_app! macro, JNI symbol export
25+ ├── libs/
26+ │ └── vespera-bridge/ # Java library (com.devfive.vespera.bridge)
27+ │ ├── VesperaBridge.java # JNI native loader + dispatch
28+ │ └── VesperaProxyController.java # Auto-configured Spring proxy
29+ ├── examples/
30+ │ ├── axum-example/ # Standard axum server demo
31+ │ └── rust-jni-demo/ # JNI + standalone server demo
32+ │ ├── src/ # Rust: routes, create_app(), jni_app!
33+ │ └── java/demo-app/ # Java: Spring Boot proxy
1934```
2035
2136## WHERE TO LOOK
@@ -30,6 +45,12 @@ vespera/
3045| Modify schema_type! macro | ` crates/vespera_macro/src/schema_macro.rs ` | Type derivation & SeaORM support |
3146| Add core types | ` crates/vespera_core/src/ ` | OpenAPI spec types |
3247| Test new features | ` examples/axum-example/ ` | Add route, run example |
48+ | In-process dispatch | ` crates/vespera_inprocess/src/lib.rs ` | RequestEnvelope → Router → ResponseEnvelope |
49+ | App factory (FFI pattern) | ` crates/vespera_inprocess/src/lib.rs ` | register_app(), dispatch_from_json() |
50+ | JNI integration | ` crates/vespera_jni/src/lib.rs ` | RUNTIME, jni_app! macro, JNI symbol export |
51+ | Java bridge library | ` libs/vespera-bridge/ ` | com.devfive.vespera.bridge package |
52+ | JNI demo (Rust) | ` examples/rust-jni-demo/src/ ` | Routes + vespera::jni_app! |
53+ | JNI demo (Java) | ` examples/rust-jni-demo/java/ ` | Spring Boot proxy app |
3354
3455## KEY COMPONENTS
3556
@@ -41,13 +62,93 @@ vespera/
4162| ` vespera_macro/src/parser/parameters.rs ` | ~ 845 | Extract path/query params from handlers |
4263| ` vespera_macro/src/openapi_generator.rs ` | ~ 808 | OpenAPI doc assembly |
4364| ` vespera_macro/src/collector.rs ` | ~ 707 | Filesystem route scanning |
65+ | ` vespera_inprocess/src/lib.rs ` | ~ 175 | In-process dispatch + app factory |
66+ | ` vespera_jni/src/lib.rs ` | ~ 95 | JNI RUNTIME + jni_app! macro + JNI symbol |
67+
68+ ## CRATE DEPENDENCY GRAPH
69+
70+ ```
71+ vespera (OpenAPI framework)
72+ ├── vespera_core
73+ ├── vespera_macro
74+ ├── vespera_inprocess (optional, feature = "inprocess")
75+ └── vespera_jni (optional, feature = "jni", implies "inprocess")
76+
77+ vespera_inprocess (transport layer — no JNI deps)
78+ ├── axum (direct — owns Router re-export)
79+ ├── http, http-body-util, tower
80+ ├── serde, serde_json
81+ └── tokio (rt only — for dispatch_from_json Runtime param)
82+
83+ vespera_jni (JNI glue — thin layer)
84+ ├── vespera_inprocess (via workspace)
85+ ├── jni
86+ └── tokio (rt-multi-thread — for LazyLock<Runtime>)
87+
88+ rust-jni-demo (example — depends on vespera ONLY)
89+ └── vespera = { features = ["jni"] }
90+ ```
91+
92+ ## USER-FACING API
93+
94+ Users depend on ` vespera ` only. Internal crates are never depended on directly.
95+
96+ ``` toml
97+ # Cargo.toml — the only dependency needed
98+ [dependencies ]
99+ vespera = { version = " ..." , features = [" jni" ] }
100+ ```
101+
102+ ``` rust
103+ // lib.rs — all imports come from vespera
104+ use vespera :: {axum, vespera};
105+
106+ pub fn create_app () -> axum :: Router {
107+ vespera! (title = " My API" , version = " 1.0.0" )
108+ }
109+
110+ vespera :: jni_app! (create_app );
111+ ```
112+
113+ Feature flags:
114+
115+ | Feature | Re-exports | Adds |
116+ | ---------| -----------| ------|
117+ | ` inprocess ` | ` vespera::inprocess ` (= ` vespera_inprocess ` ) | dispatch, register_app, envelopes |
118+ | ` jni ` | ` vespera::jni ` (= ` vespera_jni ` ) + implies ` inprocess ` | RUNTIME, jni_app!, JNI symbol |
119+
120+ ## JNI ARCHITECTURE
121+
122+ ```
123+ Java (Spring Boot) Rust (cdylib) vespera crates
124+ ───────────────── ────────────── ─────────────────
125+ VesperaBridge.init() → JNI_OnLoad vespera_inprocess::register_app()
126+ ↓ ↓
127+ VesperaBridge.dispatch() → JNI symbol vespera_inprocess::dispatch_from_json()
128+ ↓ ↓ ↓
129+ VesperaProxyController catch_unwind router.oneshot(request)
130+ ↓ ↓ ↓
131+ ResponseEntity JSON envelope axum handlers
132+ ```
133+
134+ ### Rust side (example app — 2 lines of JNI code):
135+ ``` rust
136+ pub fn create_app () -> axum :: Router { vespera! (... ) }
137+ vespera :: jni_app! (create_app );
138+ ```
139+
140+ ### Java side (user app — 1 meaningful line):
141+ ``` java
142+ VesperaBridge . init(" rust_jni_demo" );
143+ SpringApplication . run(DemoApplication . class, args);
144+ ```
44145
45146## SCHEMA_TYPE! MACRO
46147
47148Generate request/response types from existing structs with powerful transformations.
48149
49150### Key Features
50- - ** Same-file Model reference** : ` schema_type!(Schema from Model, name = "UserSchema") ` - infers module path from file location
151+ - ** Same-file Model reference** : ` schema_type!(Schema from Model, name = "UserSchema") `
51152- ** Cross-file reference** : ` schema_type!(Response from crate::models::user::Model, omit = ["password"]) `
52153- ** SeaORM integration** : Automatic conversion of ` HasOne ` , ` BelongsTo ` , ` HasMany ` relations
53154- ** Chrono conversion** : ` DateTimeWithTimeZone ` → ` vespera::chrono::DateTime<FixedOffset> `
@@ -66,55 +167,50 @@ Generate request/response types from existing structs with powerful transformati
66167| ` rename_all ` | Serde rename strategy |
67168| ` ignore ` | Skip Schema derive |
68169
69- ### Module Path Resolution
70- When using simple ` Model ` path (no ` crate:: ` prefix):
71- 1 . ` find_struct_from_path() ` calls ` find_struct_by_name_in_all_files() `
72- 2 . Uses ` schema_name ` hint to disambiguate (e.g., "UserSchema" → prefers ` user.rs ` )
73- 3 . ` file_path_to_module_path() ` infers module path from file location
74- 4 . This enables ` super:: ` resolution in relation types
75-
76170## CONVENTIONS
77171
78172- ** Rust 2024 edition** across all crates
79173- ** Workspace dependencies** : Internal crates use ` { workspace = true } `
80- - ** Version sync** : All crates at 0.1.19
81174- ** Test frameworks** : ` rstest ` for unit tests, ` insta ` for snapshots
82175- ** No ` build.rs ` ** : All code gen via proc-macros at compile time
176+ - ** No direct axum dep in examples** : Use ` vespera::axum ` re-export
177+ - ** No direct vespera_jni/vespera_inprocess dep** : Use ` vespera ` features
178+ - ** Java package** : ` com.devfive.vespera.bridge ` (fixed for JNI symbol stability)
179+ - ** Java build** : Gradle (Kotlin DSL), published to GitHub Packages
83180
84181## ANTI-PATTERNS (THIS PROJECT)
85182
86183- ** NEVER** add ` build.rs ` - macro handles compile-time generation
87184- ** NEVER** manually register routes - ` vespera! ` macro discovers them
88185- ** NEVER** write OpenAPI JSON by hand - generated from code
186+ - ** NEVER** write JNI boilerplate in examples - use ` vespera::jni_app! ` macro
187+ - ** NEVER** parse domain JSON in Java - Spring is a proxy, Rust owns business logic
188+ - ** NEVER** depend on axum directly in examples - use ` vespera::axum `
189+ - ** NEVER** depend on ` vespera_jni ` or ` vespera_inprocess ` directly - use ` vespera ` features
190+ - ** NEVER** put transport logic in vespera core - use ` vespera_inprocess ` / ` vespera_jni `
89191- Route functions ** MUST** be ` pub async fn `
90192
91- ## ARCHITECTURE FLOW
92-
93- ```
94- User writes: vespera!() macro at compile-time:
95- ┌──────────────┐ ┌────────────────────────────────────────┐
96- │ src/routes/ │ ──── │ 1. Scan filesystem for .rs files │
97- │ users.rs │ │ 2. Parse #[route] attributes │
98- │ posts.rs │ │ 3. Extract handler signatures │
99- └──────────────┘ │ 4. Generate Axum Router code │
100- │ 5. Build OpenAPI spec │
101- │ 6. Write openapi.json (optional) │
102- │ 7. Inject Swagger/ReDoc routes │
103- └────────────────────────────────────────┘
104- ```
105-
106193## COMMANDS
107194
108195``` bash
109196# Development
110197cargo build # Build all crates
111198cargo test --workspace # Run all tests
112199cargo test -p vespera_macro # Test macros only
200+ cargo test -p rust-jni-demo # Test JNI demo
113201
114- # Run example
202+ # Run axum example
115203cd examples/axum-example
116204cargo run # Starts server on :3000
117- # Visit http://localhost:3000/docs for Swagger UI
205+
206+ # Run JNI demo (standalone Rust server)
207+ cargo run -p rust-jni-demo # Starts server on :3000
208+
209+ # Run JNI demo (Java + Rust)
210+ cd libs/vespera-bridge && ./gradlew jar
211+ cargo build -p rust-jni-demo --release
212+ cd examples/rust-jni-demo/java && ./gradlew :demo-app:bootJar
213+ java -jar demo-app/build/libs/demo-app-0.1.0.jar
118214
119215# Check generated OpenAPI
120216cat examples/axum-example/openapi.json
@@ -126,3 +222,5 @@ cat examples/axum-example/openapi.json
126222- OpenAPI files are ** regenerated on every build** when ` openapi = "..." ` specified
127223- ` CARGO_MANIFEST_DIR ` env var used to locate ` src/routes/ ` folder
128224- Generic types in schemas require ` #[derive(Schema)] ` on all type params
225+ - JNI native library can be bundled inside the fat JAR for single-file deployment
226+ - ` VesperaBridge.init() ` auto-extracts bundled native lib to temp, falls back to system path
0 commit comments