Skip to content

Commit 4a63ef6

Browse files
committed
docs: improve cookbook and learning path
- Added new recipes: - Advanced Middleware (Rate Limit, Dedup, Cache) - Audit Logging (GDPR/SOC2 compliance) - OAuth2 Client - Updated Learning Path (curriculum.md) to include new modules. - Updated Cookbook Summary (SUMMARY.md). - Updated documentation inventory and coverage reports.
1 parent fa58f53 commit 4a63ef6

9 files changed

Lines changed: 442 additions & 27 deletions

File tree

docs/.agent/docs_coverage.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
| Links | `recipes/pagination.md` | `rustapi-core/src/hateoas.rs` | OK |
1313
| **Extras** | | | |
1414
| Auth (JWT) | `recipes/jwt_auth.md` | `rustapi-extras/src/jwt` | OK |
15+
| Auth (OAuth2) | `recipes/oauth2_client.md` | `rustapi-extras/src/oauth2` | OK |
1516
| Security | `recipes/csrf_protection.md` | `rustapi-extras/src/security` | OK |
1617
| Observability | `crates/rustapi_extras.md` | `rustapi-extras/src/telemetry` | OK |
18+
| Audit Logging | `recipes/audit_logging.md` | `rustapi-extras/src/audit` | OK |
19+
| Middleware (Advanced) | `recipes/advanced_middleware.md` | `rustapi-extras/src/{rate_limit, dedup, cache}` | OK |
1720
| **Jobs** | | | |
1821
| Job Queue (Crate) | `crates/rustapi_jobs.md` | `rustapi-jobs` | OK |
1922
| Background Jobs (Recipe) | `recipes/background_jobs.md` | `rustapi-jobs` | OK |

docs/.agent/docs_inventory.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@
88
| `docs/cookbook/src/getting_started/installation.md` | Installation instructions | Docs | OK |
99
| `docs/cookbook/src/learning/README.md` | Learning path entry point | Docs | OK |
1010
| `docs/cookbook/src/recipes/*.md` | Specific implementation guides | Docs | OK |
11+
| `docs/cookbook/src/recipes/advanced_middleware.md` | Recipe for Rate Limit, Dedup, Cache | Docs | OK |
12+
| `docs/cookbook/src/recipes/audit_logging.md` | Recipe for Audit Logging | Docs | OK |
13+
| `docs/cookbook/src/recipes/oauth2_client.md` | Recipe for OAuth2 Client | Docs | OK |
1114
| `crates/rustapi-core/src/hateoas.rs` | API Reference for HATEOAS | rustapi-core | OK |
1215
| `crates/rustapi-core/src/extract.rs` | API Reference for Extractors | rustapi-core | OK |

docs/.agent/last_run.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"last_processed_ref": "v0.1.335",
3-
"date": "2026-02-15",
4-
"notes": "Fixed critical inaccuracy in SSR recipe. Updated recipes index to be comprehensive. Verified docs coverage."
3+
"date": "2026-02-16",
4+
"notes": "Added recipes for Advanced Middleware, Audit Logging, and OAuth2 Client. Updated Learning Path to include these features."
55
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Run Report: 2026-02-16
2+
3+
## Detected Version
4+
- **Ref:** v0.1.335
5+
- **Status:** No version change detected. Running "Continuous Improvement" phase.
6+
7+
## Changes
8+
### Cookbook Improvements
9+
- **New Recipe:** `recipes/advanced_middleware.md`
10+
- Covers Rate Limiting (`RateLimitLayer`), Request Deduplication (`DedupLayer`), and Response Caching (`CacheLayer`).
11+
- **New Recipe:** `recipes/audit_logging.md`
12+
- Covers Audit Events (`AuditEvent`), Actions (`AuditAction`), Compliance (`ComplianceInfo`), and GDPR/SOC2 features.
13+
- **New Recipe:** `recipes/oauth2_client.md`
14+
- Covers OAuth2 Client configuration (`OAuth2Config`) and authorization flow (`OAuth2Client`).
15+
16+
### Learning Path Improvements
17+
- **Curriculum Update:** `learning/curriculum.md`
18+
- Added **Module 8: Advanced Middleware** (Phase 3).
19+
- Added **Module 7: Authentication** expanded to include OAuth2.
20+
- Added **Module 12: Observability & Auditing** (Phase 4).
21+
- Renumbered subsequent modules to maintain sequence.
22+
23+
### Documentation Tracking
24+
- Updated `docs_inventory.md` with new recipe files.
25+
- Updated `docs_coverage.md` to reflect coverage of `rate-limit`, `dedup`, `cache`, `audit`, and `oauth2-client` features in `rustapi-extras`.
26+
27+
## TODOs / Next Steps
28+
- Validate links in new recipes.
29+
- Consider adding a dedicated recipe for "Guard" (RBAC) middleware once the feature stabilizes.
30+
- Verify `rustapi-extras` feature flags in examples against `Cargo.toml`.

docs/cookbook/src/SUMMARY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,20 @@
3131
- [Creating Resources](recipes/crud_resource.md)
3232
- [Pagination & HATEOAS](recipes/pagination.md)
3333
- [JWT Authentication](recipes/jwt_auth.md)
34+
- [OAuth2 Client](recipes/oauth2_client.md)
3435
- [CSRF Protection](recipes/csrf_protection.md)
3536
- [Database Integration](recipes/db_integration.md)
3637
- [Testing & Mocking](recipes/testing.md)
3738
- [File Uploads](recipes/file_uploads.md)
3839
- [Background Jobs](recipes/background_jobs.md)
3940
- [Custom Middleware](recipes/custom_middleware.md)
41+
- [Advanced Middleware](recipes/advanced_middleware.md)
4042
- [Real-time Chat](recipes/websockets.md)
4143
- [Server-Side Rendering (SSR)](recipes/server_side_rendering.md)
4244
- [AI Integration (TOON)](recipes/ai_integration.md)
4345
- [Production Tuning](recipes/high_performance.md)
4446
- [Resilience Patterns](recipes/resilience.md)
47+
- [Audit Logging](recipes/audit_logging.md)
4548
- [Time-Travel Debugging (Replay)](recipes/replay.md)
4649
- [Deployment](recipes/deployment.md)
4750
- [HTTP/3 (QUIC)](recipes/http3_quic.md)

docs/cookbook/src/learning/curriculum.md

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,37 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
107107

108108
**Goal:** Security, Real-time, and Production readiness.
109109

110-
### Module 7: Authentication (JWT)
110+
### Module 7: Authentication (JWT & OAuth2)
111111
- **Prerequisites:** Phase 2.
112-
- **Reading:** [JWT Auth Recipe](../recipes/jwt_auth.md).
113-
- **Task:** Implement a login route that returns a JWT. Protect user routes with `AuthUser` extractor.
112+
- **Reading:** [JWT Auth Recipe](../recipes/jwt_auth.md), [OAuth2 Client](../recipes/oauth2_client.md).
113+
- **Task:**
114+
1. Implement a login route that returns a JWT.
115+
2. Protect user routes with `AuthUser` extractor.
116+
3. (Optional) Implement "Login with Google" using `OAuth2Client`.
114117
- **Expected Output:** Protected routes return `401 Unauthorized` without a valid token.
115118
- **Pitfalls:** Hardcoding secrets. Not checking token expiration.
116119

117120
#### 🧠 Knowledge Check
118121
1. What is the role of the `AuthUser` extractor?
119-
2. How do you protect a route with JWT?
122+
2. How does OAuth2 PKCE improve security?
120123
3. Where should you store the JWT secret?
121124

122-
### Module 8: WebSockets & Real-time
125+
### Module 8: Advanced Middleware
126+
- **Prerequisites:** Module 7.
127+
- **Reading:** [Advanced Middleware](../recipes/advanced_middleware.md).
128+
- **Task:**
129+
1. Apply `RateLimitLayer` to your login endpoint (10 requests/minute).
130+
2. Add `DedupLayer` to a payment endpoint.
131+
3. Cache the response of a public "stats" endpoint.
132+
- **Expected Output:** Sending 11 login attempts results in `429 Too Many Requests`.
133+
- **Pitfalls:** Caching responses that contain user-specific data.
134+
135+
#### 🧠 Knowledge Check
136+
1. What header indicates when the rate limit resets?
137+
2. Why is request deduplication important for payments?
138+
3. Which requests are typically safe to cache?
139+
140+
### Module 9: WebSockets & Real-time
123141
- **Prerequisites:** Phase 2.
124142
- **Reading:** [WebSockets Recipe](../recipes/websockets.md).
125143
- **Task:** Create a chat endpoint where users can broadcast messages.
@@ -131,21 +149,21 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
131149
2. Can you share state between HTTP handlers and WebSocket handlers?
132150
3. What happens if a WebSocket handler panics?
133151

134-
### Module 9: Production Readiness & Deployment
152+
### Module 10: Production Readiness & Deployment
135153
- **Prerequisites:** Phase 3.
136154
- **Reading:** [Production Tuning](../recipes/high_performance.md), [Resilience](../recipes/resilience.md), [Deployment](../recipes/deployment.md).
137155
- **Task:**
138-
1. Add `RateLimitLayer`, `CompressionLayer`, and `TimeoutLayer`.
156+
1. Add `CompressionLayer`, and `TimeoutLayer`.
139157
2. Use `cargo rustapi deploy docker` to generate a Dockerfile.
140158
- **Expected Output:** A resilient API ready for deployment.
141159
- **Pitfalls:** Setting timeouts too low for slow operations.
142160

143161
#### 🧠 Knowledge Check
144-
1. Why is rate limiting important?
162+
1. Why is timeout middleware important?
145163
2. What command generates a production Dockerfile?
146164
3. How do you enable compression for responses?
147165

148-
### Module 10: Background Jobs & Testing
166+
### Module 11: Background Jobs & Testing
149167
- **Prerequisites:** Phase 3.
150168
- **Reading:** [Background Jobs Recipe](../recipes/background_jobs.md), [Testing Strategy](../concepts/testing.md).
151169
- **Task:**
@@ -162,7 +180,7 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
162180
### 🏆 Phase 3 Capstone: "The Real-Time Collaboration Tool"
163181
**Objective:** Build a real-time collaborative note-taking app.
164182
**Requirements:**
165-
- **Auth:** Users must log in to edit notes.
183+
- **Auth:** Users must log in (JWT or OAuth2) to edit notes.
166184
- **Real-time:** Changes to a note are broadcast to all viewers via WebSockets.
167185
- **Jobs:** When a note is deleted, schedule a background job to archive it (simulate archive).
168186
- **Resilience:** Rate limit API requests to prevent abuse.
@@ -174,22 +192,22 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
174192

175193
**Goal:** Build observable, resilient, and high-performance distributed systems.
176194

177-
### Module 11: Observability
195+
### Module 12: Observability & Auditing
178196
- **Prerequisites:** Phase 3.
179-
- **Reading:** [Observability (Extras)](../crates/rustapi_extras.md#observability), [Structured Logging](../crates/rustapi_extras.md#structured-logging).
197+
- **Reading:** [Observability (Extras)](../crates/rustapi_extras.md#observability), [Audit Logging](../recipes/audit_logging.md).
180198
- **Task:**
181-
1. Enable `structured-logging` and `otel` features.
182-
2. Configure tracing to export spans to Jaeger (or console for dev).
183-
3. Add custom metrics for "active_users" and "jobs_processed".
184-
- **Expected Output:** Logs are JSON formatted with trace IDs. Metrics endpoint exposes Prometheus data.
185-
- **Pitfalls:** High cardinality in metric labels (e.g., using user IDs as labels).
199+
1. Enable `structured-logging` and `otel`.
200+
2. Configure tracing to export spans.
201+
3. Implement `AuditStore` and log a "User Login" event with IP address.
202+
- **Expected Output:** Logs are JSON formatted. Audit log contains a new entry for every login.
203+
- **Pitfalls:** High cardinality in metric labels.
186204

187205
#### 🧠 Knowledge Check
188-
1. What is the difference between logging and tracing?
189-
2. How do you correlate logs across microservices?
190-
3. What is the standard format for structured logs in RustAPI?
206+
1. What is the difference between logging and auditing?
207+
2. Which fields are required in an `AuditEvent`?
208+
3. How does structured logging aid debugging?
191209

192-
### Module 12: Resilience & Security
210+
### Module 13: Resilience & Security
193211
- **Prerequisites:** Phase 3.
194212
- **Reading:** [Resilience Patterns](../recipes/resilience.md), [Time-Travel Debugging](../recipes/replay.md).
195213
- **Task:**
@@ -204,7 +222,7 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
204222
2. Why is jitter important in retry strategies?
205223
3. How does Time-Travel Debugging help with "Heisenbugs"?
206224

207-
### Module 13: High Performance
225+
### Module 14: High Performance
208226
- **Prerequisites:** Phase 3.
209227
- **Reading:** [HTTP/3 (QUIC)](../recipes/http3_quic.md), [Performance Tuning](../recipes/high_performance.md).
210228
- **Task:**
@@ -226,6 +244,7 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
226244
- **Processing:** Push events to a `rustapi-jobs` queue (Redis backend).
227245
- **Storage:** Workers process events and store aggregates in a database.
228246
- **Observability:** Full tracing from ingestion to storage.
247+
- **Audit:** Log all configuration changes to the system.
229248
- **Resilience:** Circuit breakers on database writes.
230249
- **Testing:** Load test the ingestion endpoint (e.g., with k6 or similar) and observe metrics.
231250

@@ -235,7 +254,7 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
235254

236255
**Goal:** Master integration with AI, gRPC, and server-side rendering.
237256

238-
### Module 14: Server-Side Rendering (SSR)
257+
### Module 15: Server-Side Rendering (SSR)
239258
- **Prerequisites:** Phase 2.
240259
- **Reading:** [SSR Recipe](../recipes/server_side_rendering.md).
241260
- **Task:** Create a dashboard showing system status using `rustapi-view`.
@@ -247,7 +266,7 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
247266
2. How do you pass data to a template?
248267
3. How does template reloading work in debug mode?
249268

250-
### Module 15: gRPC Microservices
269+
### Module 16: gRPC Microservices
251270
- **Prerequisites:** Phase 3.
252271
- **Reading:** [gRPC Recipe](../recipes/grpc_integration.md).
253272
- **Task:** Run a gRPC service alongside your HTTP API that handles internal user lookups.
@@ -259,7 +278,7 @@ This curriculum is designed to take you from a RustAPI beginner to an advanced u
259278
2. Can HTTP and gRPC share the same Tokio runtime?
260279
3. Why might you want to run both in the same process?
261280

262-
### Module 16: AI Integration (TOON)
281+
### Module 17: AI Integration (TOON)
263282
- **Prerequisites:** Phase 2.
264283
- **Reading:** [AI Integration Recipe](../recipes/ai_integration.md).
265284
- **Task:** Create an endpoint that returns standard JSON for browsers but TOON for `Accept: application/toon`.
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Advanced Middleware: Rate Limiting, Caching, and Deduplication
2+
3+
As your API grows, you'll need to protect it from abuse and optimize performance. RustAPI provides a suite of advanced middleware in `rustapi-extras` to handle these concerns efficiently.
4+
5+
These patterns are essential for the "Enterprise Platform" learning path and high-traffic services.
6+
7+
## Prerequisites
8+
9+
Add the `rustapi-extras` crate with the necessary features to your `Cargo.toml`.
10+
11+
```toml
12+
[dependencies]
13+
rustapi-rs = { version = "0.1.335", features = ["full"] }
14+
# OR cherry-pick features
15+
# rustapi-extras = { version = "0.1.335", features = ["rate-limit", "dedup", "cache"] }
16+
```
17+
18+
## Rate Limiting
19+
20+
Rate limiting protects your API from being overwhelmed by too many requests from a single client. It uses a "Token Bucket" or "Fixed Window" algorithm to enforce limits.
21+
22+
### How it works
23+
The `RateLimitLayer` tracks request counts per IP address. When a limit is exceeded, it returns `429 Too Many Requests` with a `Retry-After` header.
24+
25+
### Usage
26+
27+
```rust
28+
use rustapi_rs::prelude::*;
29+
use rustapi_extras::rate_limit::RateLimitLayer;
30+
use std::time::Duration;
31+
32+
fn main() {
33+
let app = RustApi::new()
34+
.layer(
35+
RateLimitLayer::new(100, Duration::from_secs(60)) // 100 requests per minute
36+
)
37+
.route("/", get(handler));
38+
39+
// ... run app
40+
}
41+
```
42+
43+
The middleware automatically adds standard headers to responses:
44+
- `X-RateLimit-Limit`: The maximum number of requests allowed.
45+
- `X-RateLimit-Remaining`: The number of requests remaining in the current window.
46+
- `X-RateLimit-Reset`: The timestamp when the window resets.
47+
48+
## Request Deduplication
49+
50+
In distributed systems, clients may retry requests that have already been processed (e.g., due to network timeouts). Deduplication ensures that non-idempotent operations (like payments) are processed only once.
51+
52+
### How it works
53+
The `DedupLayer` checks for an `Idempotency-Key` header. If a request with the same key is seen within the TTL window, it returns `409 Conflict`.
54+
55+
### Usage
56+
57+
```rust
58+
use rustapi_rs::prelude::*;
59+
use rustapi_extras::dedup::DedupLayer;
60+
use std::time::Duration;
61+
62+
fn main() {
63+
let app = RustApi::new()
64+
.layer(
65+
DedupLayer::new()
66+
.header_name("X-Idempotency-Key") // Optional: Custom header name
67+
.ttl(Duration::from_secs(300)) // 5 minutes TTL
68+
)
69+
.route("/payments", post(payment_handler));
70+
71+
// ... run app
72+
}
73+
```
74+
75+
Clients should generate a unique UUID for each operation and send it in the `Idempotency-Key` header.
76+
77+
## Response Caching
78+
79+
Caching can significantly reduce load on your servers by serving stored responses for identical requests.
80+
81+
### How it works
82+
The `CacheLayer` stores successful responses in memory based on the request method and URI. Subsequent requests are served from the cache until the TTL expires.
83+
84+
### Usage
85+
86+
```rust
87+
use rustapi_rs::prelude::*;
88+
use rustapi_extras::cache::CacheLayer;
89+
use std::time::Duration;
90+
91+
fn main() {
92+
let app = RustApi::new()
93+
.layer(
94+
CacheLayer::new()
95+
.ttl(Duration::from_secs(60)) // Cache for 60 seconds
96+
.add_method("GET") // Cache GET requests
97+
.add_method("HEAD") // Cache HEAD requests
98+
)
99+
.route("/heavy-computation", get(heavy_handler));
100+
101+
// ... run app
102+
}
103+
```
104+
105+
Cached responses include an `X-Cache: HIT` header. Original responses have `X-Cache: MISS`.
106+
107+
## Combining Middleware
108+
109+
You can combine these layers to create a robust defense-in-depth strategy.
110+
111+
```rust
112+
let app = RustApi::new()
113+
// 1. Rate Limit (Outer): Reject excessive traffic first
114+
.layer(RateLimitLayer::new(1000, Duration::from_secs(60)))
115+
116+
// 2. Deduplication: Prevent double-processing
117+
.layer(DedupLayer::new())
118+
119+
// 3. Cache: Serve static/computed content quickly
120+
.layer(CacheLayer::new().ttl(Duration::from_secs(30)))
121+
122+
.route("/", get(handler));
123+
```
124+
125+
> **Note**: Order matters! Placing Rate Limit first saves resources by rejecting requests before they hit the cache or application logic.

0 commit comments

Comments
 (0)