From 1723f79e3eae5bd10b9456ee17d38b93ac868e15 Mon Sep 17 00:00:00 2001
From: "google-labs-jules[bot]"
<161369871+google-labs-jules[bot]@users.noreply.github.com>
Date: Sun, 8 Feb 2026 03:53:09 +0000
Subject: [PATCH 1/6] 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>
---
docs/cookbook/src/crates/rustapi_extras.md | 59 ++++++++++++++++++++-
docs/cookbook/src/crates/rustapi_jobs.md | 35 +++++++-----
docs/cookbook/src/crates/rustapi_testing.md | 9 ++++
3 files changed, 88 insertions(+), 15 deletions(-)
diff --git a/docs/cookbook/src/crates/rustapi_extras.md b/docs/cookbook/src/crates/rustapi_extras.md
index 4d27b8b6..27334a6c 100644
--- a/docs/cookbook/src/crates/rustapi_extras.md
+++ b/docs/cookbook/src/crates/rustapi_extras.md
@@ -15,6 +15,9 @@ This crate is a collection of production-ready middleware. Everything is behind
| `audit` | `AuditStore`, `AuditLogger` |
| `insight` | `InsightLayer`, `InsightStore` |
| `rate-limit` | `RateLimitLayer` |
+| `replay` | `ReplayLayer` (Time-Travel Debugging) |
+| `timeout` | `TimeoutLayer` |
+| `guard` | `PermissionGuard` |
## Middleware Usage
@@ -135,7 +138,7 @@ let app = RustApi::new()
### Structured Logging
-Emit logs as JSON for aggregators like Datadog or Splunk.
+Emit logs as JSON for aggregators like Datadog or Splunk. This is different from request logging; it formats your application logs.
```rust
use rustapi_extras::structured_logging::{StructuredLoggingLayer, JsonFormatter};
@@ -184,6 +187,33 @@ let app = RustApi::new()
.layer(ApiKeyLayer::new("my-secret-key"));
```
+### Permission Guards
+
+The `guard` feature provides role-based access control (RBAC) helpers.
+
+```rust
+use rustapi_extras::guard::PermissionGuard;
+
+// Only allows users with "admin" role
+#[rustapi_rs::get("/admin")]
+async fn admin_panel(
+ _guard: PermissionGuard<"admin">
+) -> &'static str {
+ "Welcome Admin"
+}
+```
+
+### Input Sanitization
+
+The `sanitization` feature helps prevent XSS by cleaning user input.
+
+```rust
+use rustapi_extras::sanitization::sanitize_html;
+
+let safe_html = sanitize_html("Hello");
+// Result: "Hello"
+```
+
## Resilience
### Circuit Breaker
@@ -208,6 +238,18 @@ let app = RustApi::new()
.layer(RetryLayer::default());
```
+### Timeout
+
+Ensure requests don't hang indefinitely.
+
+```rust
+use rustapi_extras::timeout::TimeoutLayer;
+use std::time::Duration;
+
+let app = RustApi::new()
+ .layer(TimeoutLayer::new(Duration::from_secs(30)));
+```
+
## Optimization
### Caching
@@ -231,3 +273,18 @@ use rustapi_extras::dedup::DedupLayer;
let app = RustApi::new()
.layer(DedupLayer::new());
```
+
+## Debugging
+
+### Time-Travel Debugging (Replay)
+
+The `replay` feature allows you to record production traffic and replay it locally for debugging.
+
+See the [Time-Travel Debugging Recipe](../recipes/replay.md) for full details.
+
+```rust
+use rustapi_extras::replay::{ReplayLayer, InMemoryReplayStore};
+
+let app = RustApi::new()
+ .layer(ReplayLayer::new(InMemoryReplayStore::new()));
+```
diff --git a/docs/cookbook/src/crates/rustapi_jobs.md b/docs/cookbook/src/crates/rustapi_jobs.md
index 49f15057..fe81c7d4 100644
--- a/docs/cookbook/src/crates/rustapi_jobs.md
+++ b/docs/cookbook/src/crates/rustapi_jobs.md
@@ -11,29 +11,36 @@ Long-running tasks shouldn't block HTTP requests. `rustapi-jobs` provides a robu
Here is how to set up a simple background job queue using the in-memory backend.
-### 1. Define the Job
+### 1. Define the Job and Data
-Jobs are simple structs that implement `Serialize` and `Deserialize`.
+Jobs are separated into two parts:
+1. The **Data** struct (the payload), which must be serializable.
+2. The **Job** struct (the handler), which contains the logic.
```rust
use serde::{Deserialize, Serialize};
use rustapi_jobs::{Job, JobContext, Result};
-use std::sync::Arc;
+use async_trait::async_trait;
+// 1. The payload data
#[derive(Serialize, Deserialize, Debug, Clone)]
-struct EmailJob {
+struct EmailJobData {
to: String,
subject: String,
body: String,
}
-// Implement the Job trait to define how to process it
-#[async_trait::async_trait]
+// 2. The handler struct (usually stateless)
+#[derive(Clone)]
+struct EmailJob;
+
+#[async_trait]
impl Job for EmailJob {
const NAME: &'static str = "email_job";
+ type Data = EmailJobData;
- async fn run(&self, _ctx: JobContext) -> Result<()> {
- println!("Sending email to {} with subject: {}", self.to, self.subject);
+ async fn execute(&self, _ctx: JobContext, data: Self::Data) -> Result<()> {
+ println!("Sending email to {} with subject: {}", data.to, data.subject);
// Simulate work
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
Ok(())
@@ -46,7 +53,7 @@ impl Job for EmailJob {
In your `main` function, initialize the queue and start the worker.
```rust
-use rustapi_jobs::{JobQueue, InMemoryBackend, EnqueueOptions};
+use rustapi_jobs::{JobQueue, InMemoryBackend};
#[tokio::main]
async fn main() -> Result<(), Box> {
@@ -56,17 +63,17 @@ async fn main() -> Result<(), Box> {
// 2. Create the queue
let queue = JobQueue::new(backend);
- // 3. Register the job type
- queue.register_job::();
+ // 3. Register the job handler
+ queue.register_job(EmailJob).await;
// 4. Start the worker in the background
let worker_queue = queue.clone();
tokio::spawn(async move {
- worker_queue.start_workers().await;
+ worker_queue.start_worker().await;
});
- // 5. Enqueue a job
- queue.enqueue(EmailJob {
+ // 5. Enqueue a job (pass the DATA, not the handler)
+ queue.enqueue::(EmailJobData {
to: "user@example.com".into(),
subject: "Welcome!".into(),
body: "Thanks for joining.".into(),
diff --git a/docs/cookbook/src/crates/rustapi_testing.md b/docs/cookbook/src/crates/rustapi_testing.md
index b500dbd2..df410e64 100644
--- a/docs/cookbook/src/crates/rustapi_testing.md
+++ b/docs/cookbook/src/crates/rustapi_testing.md
@@ -7,6 +7,15 @@
1. **In-process API testing**: Testing your endpoints without binding to a real TCP port.
2. **External service mocking**: Mocking downstream services (like payment gateways or auth providers) that your API calls.
+## Installation
+
+Add the crate to your `dev-dependencies`:
+
+```toml
+[dev-dependencies]
+rustapi-testing = { version = "0.1.300" }
+```
+
## The `TestClient`
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.
From 52b3ef812f1301883ddec52adfb6faafedfe8eef Mon Sep 17 00:00:00 2001
From: Tunay <121901995+Tuntii@users.noreply.github.com>
Date: Sun, 8 Feb 2026 18:16:00 +0300
Subject: [PATCH 2/6] Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
docs/cookbook/src/crates/rustapi_extras.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/docs/cookbook/src/crates/rustapi_extras.md b/docs/cookbook/src/crates/rustapi_extras.md
index 27334a6c..4121966c 100644
--- a/docs/cookbook/src/crates/rustapi_extras.md
+++ b/docs/cookbook/src/crates/rustapi_extras.md
@@ -283,8 +283,11 @@ The `replay` feature allows you to record production traffic and replay it local
See the [Time-Travel Debugging Recipe](../recipes/replay.md) for full details.
```rust
-use rustapi_extras::replay::{ReplayLayer, InMemoryReplayStore};
+use rustapi_extras::replay::{ReplayLayer, ReplayConfig, InMemoryReplayStore};
+
+let replay_config = ReplayConfig::default();
+let store = InMemoryReplayStore::new(1_000);
let app = RustApi::new()
- .layer(ReplayLayer::new(InMemoryReplayStore::new()));
+ .layer(ReplayLayer::new(replay_config).with_store(store));
```
From 7c92a2a9c5a51cbdbf6a72d8ec84d02bbc8af3b6 Mon Sep 17 00:00:00 2001
From: Tunay <121901995+Tuntii@users.noreply.github.com>
Date: Sun, 8 Feb 2026 18:16:09 +0300
Subject: [PATCH 3/6] Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
docs/cookbook/src/crates/rustapi_extras.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/cookbook/src/crates/rustapi_extras.md b/docs/cookbook/src/crates/rustapi_extras.md
index 4121966c..5e39c377 100644
--- a/docs/cookbook/src/crates/rustapi_extras.md
+++ b/docs/cookbook/src/crates/rustapi_extras.md
@@ -18,6 +18,7 @@ This crate is a collection of production-ready middleware. Everything is behind
| `replay` | `ReplayLayer` (Time-Travel Debugging) |
| `timeout` | `TimeoutLayer` |
| `guard` | `PermissionGuard` |
+| `sanitization` | Input sanitization utilities |
## Middleware Usage
From d73d62c3aacd701d8505ee1b5d455b9d9c4b62ca Mon Sep 17 00:00:00 2001
From: Tunay <121901995+Tuntii@users.noreply.github.com>
Date: Sun, 8 Feb 2026 18:16:19 +0300
Subject: [PATCH 4/6] Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
docs/cookbook/src/crates/rustapi_extras.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/cookbook/src/crates/rustapi_extras.md b/docs/cookbook/src/crates/rustapi_extras.md
index 5e39c377..218adb74 100644
--- a/docs/cookbook/src/crates/rustapi_extras.md
+++ b/docs/cookbook/src/crates/rustapi_extras.md
@@ -198,7 +198,7 @@ use rustapi_extras::guard::PermissionGuard;
// Only allows users with "admin" role
#[rustapi_rs::get("/admin")]
async fn admin_panel(
- _guard: PermissionGuard<"admin">
+ _guard: PermissionGuard
) -> &'static str {
"Welcome Admin"
}
From b670a337e5fb536f7761cab4ad0cb015c7c0e329 Mon Sep 17 00:00:00 2001
From: Tunay <121901995+Tuntii@users.noreply.github.com>
Date: Sun, 8 Feb 2026 18:16:49 +0300
Subject: [PATCH 5/6] Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
docs/cookbook/src/crates/rustapi_extras.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/cookbook/src/crates/rustapi_extras.md b/docs/cookbook/src/crates/rustapi_extras.md
index 218adb74..67a332a6 100644
--- a/docs/cookbook/src/crates/rustapi_extras.md
+++ b/docs/cookbook/src/crates/rustapi_extras.md
@@ -212,7 +212,7 @@ The `sanitization` feature helps prevent XSS by cleaning user input.
use rustapi_extras::sanitization::sanitize_html;
let safe_html = sanitize_html("Hello");
-// Result: "Hello"
+// Result: "<script>alert(1)</script>Hello"
```
## Resilience
From 0bd0179f31da37b649af67ee85b683e00f43d44c Mon Sep 17 00:00:00 2001
From: Tunay <121901995+Tuntii@users.noreply.github.com>
Date: Sun, 8 Feb 2026 18:17:10 +0300
Subject: [PATCH 6/6] Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
docs/cookbook/src/crates/rustapi_jobs.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/docs/cookbook/src/crates/rustapi_jobs.md b/docs/cookbook/src/crates/rustapi_jobs.md
index fe81c7d4..21be0721 100644
--- a/docs/cookbook/src/crates/rustapi_jobs.md
+++ b/docs/cookbook/src/crates/rustapi_jobs.md
@@ -69,7 +69,9 @@ async fn main() -> Result<(), Box> {
// 4. Start the worker in the background
let worker_queue = queue.clone();
tokio::spawn(async move {
- worker_queue.start_worker().await;
+ if let Err(e) = worker_queue.start_worker().await {
+ eprintln!("Worker failed: {:?}", e);
+ }
});
// 5. Enqueue a job (pass the DATA, not the handler)