Skip to content

Commit 1723f79

Browse files
docs: update cookbook for v0.1.300 and fix rustapi-jobs API
Updated the cookbook documentation to align with the current codebase state (v0.1.300). Changes: - Fixed `rustapi-jobs` documentation: - Corrected `Job` trait implementation to use `execute` method instead of `run`. - Clarified the separation between Job handler and Job Data payload. - Updated enqueueing examples to pass data struct instead of handler struct. - Updated `rustapi-extras` documentation: - Added sections for `Replay` (Time-Travel Debugging), `Timeout`, `Sanitization`, and `Guard` features. - Clarified the distinction between request logging and structured logging. - Updated `rustapi-testing` documentation: - Added missing installation instructions. Co-authored-by: Tuntii <121901995+Tuntii@users.noreply.github.com>
1 parent 6f71402 commit 1723f79

3 files changed

Lines changed: 88 additions & 15 deletions

File tree

docs/cookbook/src/crates/rustapi_extras.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ This crate is a collection of production-ready middleware. Everything is behind
1515
| `audit` | `AuditStore`, `AuditLogger` |
1616
| `insight` | `InsightLayer`, `InsightStore` |
1717
| `rate-limit` | `RateLimitLayer` |
18+
| `replay` | `ReplayLayer` (Time-Travel Debugging) |
19+
| `timeout` | `TimeoutLayer` |
20+
| `guard` | `PermissionGuard` |
1821

1922
## Middleware Usage
2023

@@ -135,7 +138,7 @@ let app = RustApi::new()
135138

136139
### Structured Logging
137140

138-
Emit logs as JSON for aggregators like Datadog or Splunk.
141+
Emit logs as JSON for aggregators like Datadog or Splunk. This is different from request logging; it formats your application logs.
139142

140143
```rust
141144
use rustapi_extras::structured_logging::{StructuredLoggingLayer, JsonFormatter};
@@ -184,6 +187,33 @@ let app = RustApi::new()
184187
.layer(ApiKeyLayer::new("my-secret-key"));
185188
```
186189

190+
### Permission Guards
191+
192+
The `guard` feature provides role-based access control (RBAC) helpers.
193+
194+
```rust
195+
use rustapi_extras::guard::PermissionGuard;
196+
197+
// Only allows users with "admin" role
198+
#[rustapi_rs::get("/admin")]
199+
async fn admin_panel(
200+
_guard: PermissionGuard<"admin">
201+
) -> &'static str {
202+
"Welcome Admin"
203+
}
204+
```
205+
206+
### Input Sanitization
207+
208+
The `sanitization` feature helps prevent XSS by cleaning user input.
209+
210+
```rust
211+
use rustapi_extras::sanitization::sanitize_html;
212+
213+
let safe_html = sanitize_html("<script>alert(1)</script>Hello");
214+
// Result: "Hello"
215+
```
216+
187217
## Resilience
188218

189219
### Circuit Breaker
@@ -208,6 +238,18 @@ let app = RustApi::new()
208238
.layer(RetryLayer::default());
209239
```
210240

241+
### Timeout
242+
243+
Ensure requests don't hang indefinitely.
244+
245+
```rust
246+
use rustapi_extras::timeout::TimeoutLayer;
247+
use std::time::Duration;
248+
249+
let app = RustApi::new()
250+
.layer(TimeoutLayer::new(Duration::from_secs(30)));
251+
```
252+
211253
## Optimization
212254

213255
### Caching
@@ -231,3 +273,18 @@ use rustapi_extras::dedup::DedupLayer;
231273
let app = RustApi::new()
232274
.layer(DedupLayer::new());
233275
```
276+
277+
## Debugging
278+
279+
### Time-Travel Debugging (Replay)
280+
281+
The `replay` feature allows you to record production traffic and replay it locally for debugging.
282+
283+
See the [Time-Travel Debugging Recipe](../recipes/replay.md) for full details.
284+
285+
```rust
286+
use rustapi_extras::replay::{ReplayLayer, InMemoryReplayStore};
287+
288+
let app = RustApi::new()
289+
.layer(ReplayLayer::new(InMemoryReplayStore::new()));
290+
```

docs/cookbook/src/crates/rustapi_jobs.md

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,36 @@ Long-running tasks shouldn't block HTTP requests. `rustapi-jobs` provides a robu
1111

1212
Here is how to set up a simple background job queue using the in-memory backend.
1313

14-
### 1. Define the Job
14+
### 1. Define the Job and Data
1515

16-
Jobs are simple structs that implement `Serialize` and `Deserialize`.
16+
Jobs are separated into two parts:
17+
1. The **Data** struct (the payload), which must be serializable.
18+
2. The **Job** struct (the handler), which contains the logic.
1719

1820
```rust
1921
use serde::{Deserialize, Serialize};
2022
use rustapi_jobs::{Job, JobContext, Result};
21-
use std::sync::Arc;
23+
use async_trait::async_trait;
2224

25+
// 1. The payload data
2326
#[derive(Serialize, Deserialize, Debug, Clone)]
24-
struct EmailJob {
27+
struct EmailJobData {
2528
to: String,
2629
subject: String,
2730
body: String,
2831
}
2932

30-
// Implement the Job trait to define how to process it
31-
#[async_trait::async_trait]
33+
// 2. The handler struct (usually stateless)
34+
#[derive(Clone)]
35+
struct EmailJob;
36+
37+
#[async_trait]
3238
impl Job for EmailJob {
3339
const NAME: &'static str = "email_job";
40+
type Data = EmailJobData;
3441

35-
async fn run(&self, _ctx: JobContext) -> Result<()> {
36-
println!("Sending email to {} with subject: {}", self.to, self.subject);
42+
async fn execute(&self, _ctx: JobContext, data: Self::Data) -> Result<()> {
43+
println!("Sending email to {} with subject: {}", data.to, data.subject);
3744
// Simulate work
3845
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
3946
Ok(())
@@ -46,7 +53,7 @@ impl Job for EmailJob {
4653
In your `main` function, initialize the queue and start the worker.
4754

4855
```rust
49-
use rustapi_jobs::{JobQueue, InMemoryBackend, EnqueueOptions};
56+
use rustapi_jobs::{JobQueue, InMemoryBackend};
5057

5158
#[tokio::main]
5259
async fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -56,17 +63,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
5663
// 2. Create the queue
5764
let queue = JobQueue::new(backend);
5865

59-
// 3. Register the job type
60-
queue.register_job::<EmailJob>();
66+
// 3. Register the job handler
67+
queue.register_job(EmailJob).await;
6168

6269
// 4. Start the worker in the background
6370
let worker_queue = queue.clone();
6471
tokio::spawn(async move {
65-
worker_queue.start_workers().await;
72+
worker_queue.start_worker().await;
6673
});
6774

68-
// 5. Enqueue a job
69-
queue.enqueue(EmailJob {
75+
// 5. Enqueue a job (pass the DATA, not the handler)
76+
queue.enqueue::<EmailJob>(EmailJobData {
7077
to: "user@example.com".into(),
7178
subject: "Welcome!".into(),
7279
body: "Thanks for joining.".into(),

docs/cookbook/src/crates/rustapi_testing.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
1. **In-process API testing**: Testing your endpoints without binding to a real TCP port.
88
2. **External service mocking**: Mocking downstream services (like payment gateways or auth providers) that your API calls.
99

10+
## Installation
11+
12+
Add the crate to your `dev-dependencies`:
13+
14+
```toml
15+
[dev-dependencies]
16+
rustapi-testing = { version = "0.1.300" }
17+
```
18+
1019
## The `TestClient`
1120

1221
Integration testing is often slow and painful because it involves spinning up a server, waiting for ports, and managing child processes. `TestClient` solves this by wrapping your `RustApi` application and executing requests directly against the service layer.

0 commit comments

Comments
 (0)