Skip to content

Commit 5141d88

Browse files
committed
docs: add v0.1.397 release notes and update changelog
1 parent a44087c commit 5141d88

2 files changed

Lines changed: 293 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,63 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.1.397] - 2026-02-26
11+
12+
### Added
13+
14+
#### Compile-Time Extractor Safety (`rustapi-macros`)
15+
- **Body-consuming extractor ordering enforced at compile time**: `Json<T>`, `Body`, `ValidatedJson<T>` must now be the last handler parameter — otherwise you get a clear compiler error instead of a silent runtime failure.
16+
- Descriptive error messages: `"Body-consuming extractors must be the last parameter"`.
17+
- Detects multiple body-consuming extractors in the same handler.
18+
19+
#### Typed Error Responses — OpenAPI Integration (`rustapi-macros`, `rustapi-core`)
20+
- New `#[errors(404 = "Not found", 403 = "Forbidden")]` attribute macro for route handlers.
21+
- Error types are automatically reflected in the OpenAPI spec with `ErrorSchema` references.
22+
- `Route::error_response()` builder method for programmatic error response registration.
23+
- Swagger UI now displays all possible error responses per endpoint.
24+
25+
#### Pagination & HATEOAS Helpers (`rustapi-core`)
26+
- **`Paginate` extractor**: `?page=2&per_page=20` with sensible defaults (page=1, per_page=20, max=100).
27+
- **`Paginated<T>` response wrapper**: JSON body with `items`/`meta`/`_links`, RFC 8288 `Link` header, `X-Total-Count` & `X-Total-Pages` headers.
28+
- **`CursorPaginate` extractor**: `?cursor=abc&limit=20` for cursor-based pagination.
29+
- **`CursorPaginated<T>` response wrapper**: `items` + `next_cursor` + `has_more`.
30+
- Helper methods: `offset()`, `limit()`, `paginate()`, `after()`, `is_first_page()`.
31+
- All types re-exported in the `rustapi-rs` prelude.
32+
33+
#### Built-in Caching Layer (`rustapi-extras`)
34+
- **Full rewrite of the caching system** with production-grade features:
35+
- In-memory response cache with LRU eviction and configurable `max_entries` (default: 10,000).
36+
- ETag generation via FNV-1a hash + automatic `If-None-Match` → 304 Not Modified.
37+
- `Cache-Control` header awareness (`no-cache`, `no-store`).
38+
- `Vary`-by-header cache key strategy.
39+
- `CacheHandle` for programmatic invalidation (by path prefix, exact key, or clear all).
40+
- `CacheBuilder` for ergonomic middleware configuration.
41+
42+
#### Event System & Lifecycle Hooks (`rustapi-core`)
43+
- **`EventBus`**: In-process pub/sub with sync and async handlers.
44+
- `on()` for sync handlers, `on_async()` for async handlers.
45+
- `emit()` (fire-and-forget) and `emit_await()` (wait for all handlers).
46+
- `handler_count()` and `topics()` introspection.
47+
- **Lifecycle hooks** on `RustApi` builder:
48+
- `.on_start(async { ... })` — runs before the server starts accepting connections.
49+
- `.on_shutdown(async { ... })` — runs on graceful shutdown.
50+
- Integrated into both `run()` and `run_with_shutdown()`.
51+
- `EventBus` re-exported in the `rustapi-rs` prelude.
52+
53+
#### Native Hot Reload / Watch Mode (`cargo-rustapi`, `rustapi-core`)
54+
- **Complete rewrite of `cargo rustapi watch`** using `notify` + `notify-debouncer-mini` — no more `cargo-watch` dependency.
55+
- 300ms debounce, configurable extension filter, smart ignore paths.
56+
- Build-before-restart: only restarts the server if `cargo build` succeeds.
57+
- Graceful process shutdown (kill + 5s timeout), crash detection with "watching for changes" recovery.
58+
- `.hot_reload(true)` builder API on `RustApi` — prints a dev-mode banner with watcher hints.
59+
- `cargo rustapi run --watch` / `--reload` / `--hot` delegates to the native watcher.
60+
61+
#### gRPC Support Published (`rustapi-grpc`)
62+
- **First crates.io release** of `rustapi-grpc v0.1.397`.
63+
- `run_rustapi_and_grpc()` for dual HTTP + gRPC server execution.
64+
- Re-exports `tonic` and `prost` for ergonomic proto service integration.
65+
- `protocol-grpc` feature flag in `rustapi-rs`.
66+
1067
### Changed
1168
- **Facade-first CORE stabilization**:
1269
- `rustapi-rs` public surface is now explicitly curated (`core`, `protocol`, `extras`, `prelude`).
@@ -17,19 +74,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1774
- Canonical naming is now `core-*`, `protocol-*`, `extras-*`.
1875
- Meta features standardized: `core`, `protocol-all`, `extras-all`, `full`.
1976
- Legacy feature names remain as compatibility aliases and are deprecated.
77+
- **Publish pipeline**: `rustapi-grpc` added to `smart_publish.ps1` and `publish.ps1` in correct dependency order.
2078

21-
### Added
79+
### Fixed
80+
- Clippy lint: `.map_or(false, ...)``.is_some_and(...)` in cache middleware.
81+
- Clippy lint: Nested `format!` macros replaced with single `format!` in ETag generation.
82+
83+
### Documentation
84+
- Expanded cookbook: gRPC, SSR, and AI skill recipes.
85+
- Learning path improvements across multiple maintenance runs.
86+
- Fixed SSR recipe and updated recipes index.
87+
88+
### Added (Governance)
2289
- **Public API governance**:
2390
- Snapshot files under `api/public/` for `rustapi-rs` (default + all-features).
24-
- New CI workflow `.github/workflows/public-api.yml`:
25-
- snapshot drift check
26-
- PR label gate requiring `breaking` or `feature` when snapshot changes.
27-
- **Compatibility contract**:
28-
- New `CONTRACT.md` defining SemVer, MSRV (1.78), deprecation and feature policies.
91+
- CI workflow for snapshot drift check and PR label gate.
92+
- **Compatibility contract**: New `CONTRACT.md` defining SemVer, MSRV (1.78), deprecation and feature policies.
2993

3094
### Deprecated
3195
- Legacy facade paths and feature aliases are soft-deprecated and scheduled for removal no earlier than two minor releases after announcement.
3296

97+
## [0.1.335] - 2026-02-13
98+
99+
### Added
100+
- Pagination cookbook recipe and synced docs to v0.1.335.
101+
- HATEOAS test schemas with manual `RustApiSchema` implementations.
102+
- RELEASES.md for release tracking.
103+
104+
### Fixed
105+
- Lint formatting in `custom_messages.rs`.
106+
- Pagination size validation (PR review feedback).
107+
- Cumulative CI failure fixes.
108+
33109
## [0.1.300] - 2026-02-06
34110

35111
### Added
@@ -304,7 +380,16 @@ This release delivers a **12x performance improvement**, bringing RustAPI from ~
304380
- `extras` meta-feature for common optional features
305381
- `full` feature for all optional features
306382

307-
[Unreleased]: https://github.com/Tuntii/RustAPI/compare/v0.1.4...HEAD
383+
[Unreleased]: https://github.com/Tuntii/RustAPI/compare/v0.1.397...HEAD
384+
[0.1.397]: https://github.com/Tuntii/RustAPI/compare/v0.1.335...v0.1.397
385+
[0.1.335]: https://github.com/Tuntii/RustAPI/compare/v0.1.300...v0.1.335
386+
[0.1.300]: https://github.com/Tuntii/RustAPI/compare/v0.1.202...v0.1.300
387+
[0.1.202]: https://github.com/Tuntii/RustAPI/compare/v0.1.15...v0.1.202
388+
[0.1.15]: https://github.com/Tuntii/RustAPI/compare/v0.1.11...v0.1.15
389+
[0.1.11]: https://github.com/Tuntii/RustAPI/compare/v0.1.10...v0.1.11
390+
[0.1.10]: https://github.com/Tuntii/RustAPI/compare/v0.1.9...v0.1.10
391+
[0.1.9]: https://github.com/Tuntii/RustAPI/compare/v0.1.8...v0.1.9
392+
[0.1.8]: https://github.com/Tuntii/RustAPI/compare/v0.1.4...v0.1.8
308393
[0.1.4]: https://github.com/Tuntii/RustAPI/compare/v0.1.3...v0.1.4
309394
[0.1.3]: https://github.com/Tuntii/RustAPI/compare/v0.1.2...v0.1.3
310395
[0.1.2]: https://github.com/Tuntii/RustAPI/compare/v0.1.1...v0.1.2

RELEASES.md

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# RustAPI v0.1.397 Release Notes
2+
3+
**Release Date**: February 26, 2026
4+
**Full Changelog**: https://github.com/Tuntii/RustAPI/compare/v0.1.335...v0.1.397
5+
6+
---
7+
8+
## 🎯 Highlights
9+
10+
This is the biggest feature release since v0.1.300. Seven major features land together, transforming RustAPI from a routing framework into a **production-ready application platform**.
11+
12+
| Feature | Crate | Impact |
13+
|---------|-------|--------|
14+
| Compile-Time Extractor Safety | `rustapi-macros` | Zero runtime surprises from body-consuming extractors |
15+
| Typed Error Responses | `rustapi-macros` + `rustapi-core` | Errors auto-reflected in OpenAPI spec |
16+
| Pagination & HATEOAS | `rustapi-core` | Offset + cursor pagination with RFC 8288 Link headers |
17+
| Built-in Caching Layer | `rustapi-extras` | LRU + ETag + `304 Not Modified` out of the box |
18+
| Event System & Lifecycle Hooks | `rustapi-core` | In-process pub/sub + `on_start` / `on_shutdown` |
19+
| Native Hot Reload | `cargo-rustapi` | Zero-dependency file watcher, no `cargo-watch` needed |
20+
| gRPC Support | `rustapi-grpc` | First crates.io release — dual HTTP + gRPC server |
21+
22+
---
23+
24+
## ⚡ Compile-Time Extractor Safety
25+
26+
Body-consuming extractors (`Json<T>`, `Body`, `ValidatedJson<T>`) **must** now be the last handler parameter. The macro emits a clear compile error instead of silently failing at runtime:
27+
28+
```rust
29+
// ✅ Compiles
30+
#[get("/users")]
31+
async fn ok(State(db): State<Db>, body: Json<CreateUser>) -> Result<Json<User>> { ... }
32+
33+
// ❌ Compile error: "Body-consuming extractors must be the last parameter"
34+
#[get("/users")]
35+
async fn bad(body: Json<CreateUser>, State(db): State<Db>) -> Result<Json<User>> { ... }
36+
```
37+
38+
Multiple body-consuming extractors in the same handler are also detected at compile time.
39+
40+
---
41+
42+
## 🏷️ Typed Error Responses (OpenAPI)
43+
44+
Declare possible error responses with `#[errors()]` — they appear automatically in Swagger UI:
45+
46+
```rust
47+
#[get("/users/{id}")]
48+
#[errors(404 = "User not found", 403 = "Insufficient permissions")]
49+
async fn get_user(Path(id): Path<Uuid>) -> Result<Json<User>> { ... }
50+
```
51+
52+
Programmatic alternative: `Route::error_response(404, "Not found")`.
53+
54+
---
55+
56+
## 📄 Pagination & HATEOAS
57+
58+
### Offset Pagination
59+
```rust
60+
async fn list(paginate: Paginate, State(db): State<Db>) -> Paginated<User> {
61+
let (users, total) = db.find_users(paginate.offset(), paginate.limit()).await;
62+
paginate.paginate(users, total)
63+
}
64+
// GET /users?page=2&per_page=20
65+
// → { items: [...], meta: { page: 2, per_page: 20, total: 150, total_pages: 8 }, _links: {...} }
66+
// → Link: <...?page=3&per_page=20>; rel="next", <...?page=1&per_page=20>; rel="prev"
67+
```
68+
69+
### Cursor Pagination
70+
```rust
71+
async fn feed(cursor: CursorPaginate) -> CursorPaginated<Post> {
72+
let posts = db.posts_after(cursor.cursor(), cursor.limit()).await;
73+
cursor.after(posts, next_cursor, has_more)
74+
}
75+
```
76+
77+
Both include `X-Total-Count` and `X-Total-Pages` headers. All types in the prelude.
78+
79+
---
80+
81+
## 🗄️ Built-in Caching Layer
82+
83+
Full rewrite with production-grade features:
84+
85+
```rust
86+
use rustapi_rs::prelude::*;
87+
88+
let app = RustApi::new()
89+
.layer(
90+
CacheBuilder::new()
91+
.max_entries(5_000)
92+
.default_ttl(Duration::from_secs(300))
93+
.vary_by(&["Accept", "Authorization"])
94+
.build()
95+
);
96+
```
97+
98+
- **LRU eviction** with configurable `max_entries`
99+
- **ETag** generation via FNV-1a hash + automatic `304 Not Modified`
100+
- **Cache-Control** awareness (`no-cache`, `no-store`)
101+
- **`CacheHandle`** for programmatic invalidation (by prefix, exact key, or clear all)
102+
103+
---
104+
105+
## 🔔 Event System & Lifecycle Hooks
106+
107+
### EventBus
108+
```rust
109+
let bus = EventBus::new();
110+
bus.on("user.created", |data| { println!("New user: {data}"); });
111+
bus.emit("user.created", "alice@example.com");
112+
```
113+
114+
Supports sync and async handlers, fire-and-forget (`emit`) and await-all (`emit_await`).
115+
116+
### Lifecycle Hooks
117+
```rust
118+
RustApi::new()
119+
.on_start(|| async { println!("🚀 Server starting..."); Ok(()) })
120+
.on_shutdown(|| async { println!("👋 Graceful shutdown"); Ok(()) })
121+
.run("0.0.0.0:8080").await;
122+
```
123+
124+
---
125+
126+
## 🔥 Native Hot Reload
127+
128+
No more `cargo install cargo-watch`:
129+
130+
```bash
131+
cargo rustapi watch # Watch mode with 300ms debounce
132+
cargo rustapi run --watch # Same via run subcommand
133+
```
134+
135+
- **Build-before-restart**: Only restarts if `cargo build` succeeds
136+
- **Crash recovery**: Watches for changes even after build failure
137+
- **Smart filtering**: Ignores `target/`, `.git/`, non-Rust files
138+
- **`.hot_reload(true)`** builder API prints dev-mode banner
139+
140+
---
141+
142+
## 🌐 gRPC Support (First Release)
143+
144+
`rustapi-grpc` is now on **crates.io** for the first time:
145+
146+
```toml
147+
[dependencies]
148+
rustapi-rs = { version = "0.1.397", features = ["protocol-grpc"] }
149+
```
150+
151+
```rust
152+
use rustapi_grpc::run_rustapi_and_grpc;
153+
154+
run_rustapi_and_grpc(http_app, grpc_router, "[::]:8080", "[::]:50051").await;
155+
```
156+
157+
Re-exports `tonic` and `prost` for seamless proto integration.
158+
159+
---
160+
161+
## 🏗️ Facade Stabilization & Governance
162+
163+
- Public API surface explicitly curated under `core`, `protocol`, `extras`, `prelude` modules
164+
- API snapshot files (`api/public/`) with CI drift check
165+
- `CONTRACT.md` defining SemVer contract, MSRV (1.78), deprecation policy
166+
- Feature taxonomy: `core-*`, `protocol-*`, `extras-*` canonical names
167+
168+
---
169+
170+
## 🔧 Fixes & Maintenance
171+
172+
- Clippy: `.map_or(false, ...)``.is_some_and(...)` in cache middleware
173+
- Clippy: Nested `format!` → single `format!` in ETag generation
174+
- Publish pipeline: `rustapi-grpc` added to both publish scripts
175+
176+
---
177+
178+
## 📦 Upgrade Guide
179+
180+
```toml
181+
# Cargo.toml
182+
rustapi-rs = "0.1.397"
183+
184+
# For new features:
185+
rustapi-rs = { version = "0.1.397", features = ["full"] }
186+
```
187+
188+
No breaking changes. Deprecated legacy feature aliases still work and will be removed no earlier than two minor releases after this announcement.
189+
190+
---
191+
192+
## What's Changed (PRs)
193+
194+
- Add lifecycle hooks, pagination, and cache (#139)
195+
- Fix review feedback: deduplication, pagination validation, cache correctness (#140)
196+
- docs: cookbook expansion and learning path improvements (#132)
197+
- core: stabilize facade API surface, feature taxonomy, and public-api CI gate (#122)
198+
- Add optional rustapi-grpc crate (tonic/prost) (#118)
199+
- docs: multiple learning path and cookbook improvements (#109, #112, #120, #121, #123-126, #129)
200+
201+
**Full Changelog**: https://github.com/Tuntii/RustAPI/compare/v0.1.335...v0.1.397

0 commit comments

Comments
 (0)