Skip to content

Commit 867d4ca

Browse files
committed
Add validation integration and macro-based route support
Introduces the ValidatedJson extractor for request body validation using the rustapi-validate crate, and integrates validation error conversion into ApiError. Adds Route and RouteHandler traits, route! macro, and mount_route for macro-based route registration. Updates dependencies and workspace configuration to include rustapi-validate. Removes AGENTS.md and Copilot instructions in favor of a unified .agent/INSTRUCTIONS.md.
1 parent a0b6041 commit 867d4ca

18 files changed

Lines changed: 1040 additions & 356 deletions

File tree

.agent/INSTRUCTIONS.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# RustAPI - Project Instructions
2+
3+
> **Last Updated:** December 30, 2025
4+
> **Status:** Phase 1 Complete ✅ | Phase 2 In Progress 🔄
5+
6+
---
7+
8+
## Project Overview
9+
10+
**RustAPI** is a FastAPI-inspired web framework for Rust that prioritizes developer experience (DX) while maintaining Rust's performance and memory safety.
11+
12+
### Core Philosophy
13+
- **5-line Hello World** - Minimal boilerplate
14+
- **Type-driven development** - Structs as schemas
15+
- **API surface is ours, engines can change** - All dependencies wrapped
16+
- **Batteries included but modular** - Easy start, escape hatches available
17+
18+
---
19+
20+
## Project Structure
21+
22+
```
23+
RustAPI/
24+
├── Cargo.toml # Workspace root
25+
├── README.md # PRD + Manifesto (detailed)
26+
├── memories/
27+
│ ├── TASKLIST.md # Phase-by-phase task list
28+
│ └── rustapi_memory_bank.md # Technical reference + decisions
29+
├── crates/
30+
│ ├── rustapi-rs/ # Public facade (crates.io name)
31+
│ ├── rustapi-core/ # Router, extractors, responses, server
32+
│ ├── rustapi-macros/ # Proc-macros (#[rustapi::main], etc.)
33+
│ └── rustapi-validate/ # Validation system (validator wrapper)
34+
└── examples/
35+
└── hello-world/ # Working example ✅
36+
```
37+
38+
---
39+
40+
## Phase Summary
41+
42+
| Phase | Status | Description |
43+
|-------|--------|-------------|
44+
| Phase 1: MVP | ✅ Complete | Router, extractors, responses, basic server |
45+
| Phase 2: Validation + OpenAPI | 🔄 In Progress | Validation wrapper, OpenAPI docs, Swagger UI |
46+
| Phase 3: Batteries Included | ⏳ Planned | Middleware, JWT, CORS, rate limiting |
47+
| Phase 4: v1.0 | ⏳ Planned | Polish, tests, documentation, crates.io publish |
48+
49+
---
50+
51+
## Key Architecture Decisions
52+
53+
1. **Crate name:** `rustapi-rs` (for crates.io)
54+
2. **validator crate:** Wrapper in v0.x, custom engine in v1.x
55+
3. **utoipa crate:** Wrapper only, never expose types
56+
4. **MSRV:** Rust 1.75+
57+
5. **Path params:** `{param}` format (converted to `:param` for matchit)
58+
59+
---
60+
61+
## Development Commands
62+
63+
```powershell
64+
# Build entire workspace
65+
cargo build
66+
67+
# Run hello-world example
68+
cargo run -p hello-world
69+
70+
# Run tests
71+
cargo test --workspace
72+
73+
# Test validation crate
74+
cargo test -p rustapi-validate
75+
76+
# Test specific endpoint
77+
Invoke-RestMethod -Uri http://127.0.0.1:8080/
78+
Invoke-RestMethod -Uri http://127.0.0.1:8080/users/42
79+
```
80+
81+
---
82+
83+
## Current Implementation Status
84+
85+
### ✅ Completed (Phase 1)
86+
- **Router:** Radix tree with matchit, path params, method routing
87+
- **Extractors:** `Json<T>`, `Path<T>`, `Query<T>`, `State<T>`, `Body`
88+
- **Responses:** `Json<T>`, `Created<T>`, `NoContent`, `Html<T>`, `Redirect`
89+
- **Errors:** `ApiError`, `Result<T>` type alias
90+
- **Server:** Hyper 1.x, graceful shutdown, tracing
91+
92+
### 🔄 In Progress (Phase 2)
93+
- **Validation:** `rustapi-validate` crate exists with:
94+
- `Validate` trait (wraps `validator::Validate`)
95+
- `FieldError`, `ValidationError` types
96+
- 422 JSON error format
97+
- Tests passing
98+
- **Pending:**
99+
- `ValidatedJson<T>` extractor
100+
- Integration with `rustapi-core`
101+
- `rustapi-openapi` crate (utoipa wrapper)
102+
- Swagger UI embedding
103+
104+
---
105+
106+
## Usage Example (Current)
107+
108+
```rust
109+
use rustapi_rs::prelude::*;
110+
111+
#[derive(Serialize)]
112+
struct HelloResponse { message: String }
113+
114+
async fn hello() -> Json<HelloResponse> {
115+
Json(HelloResponse { message: "Hello!".into() })
116+
}
117+
118+
#[tokio::main]
119+
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
120+
RustApi::new()
121+
.route("/", get(hello))
122+
.run("127.0.0.1:8080")
123+
.await
124+
}
125+
```
126+
127+
---
128+
129+
## Target Usage (After Phase 2)
130+
131+
```rust
132+
use rustapi_rs::prelude::*;
133+
134+
#[derive(Schema, Validate, Deserialize)]
135+
struct RegisterRequest {
136+
#[validate(email)]
137+
email: String,
138+
#[validate(length(min = 8))]
139+
password: String,
140+
}
141+
142+
#[derive(Schema, Serialize)]
143+
struct UserOut { id: i64, email: String }
144+
145+
async fn register(body: ValidatedJson<RegisterRequest>) -> Result<Created<UserOut>> {
146+
// body is already validated!
147+
Ok(Created(UserOut { id: 1, email: body.email.clone() }))
148+
}
149+
150+
#[tokio::main]
151+
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
152+
RustApi::new()
153+
.route("/register", post(register))
154+
.docs("/docs") // Swagger UI
155+
.openapi("/api.json") // OpenAPI spec
156+
.run("127.0.0.1:8080")
157+
.await
158+
}
159+
```
160+
161+
---
162+
163+
## Related Files
164+
165+
| File | Purpose |
166+
|------|---------|
167+
| `README.md` | Full PRD and manifesto |
168+
| `memories/TASKLIST.md` | Detailed phase-by-phase tasks |
169+
| `memories/rustapi_memory_bank.md` | Technical reference |
170+
| `examples/hello-world/` | Working example |

.github/copilot-instructions.md

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)