p9: add Contributing section — development setup, coding standards, testing, benchmarking, docs guide

swadhinbiswas committed 3 months ago
d81e1e5
1 parent 6165b3e
commit d81e1e5
5 files changed
+499 -0
▼docs_site/src/content/docs/contributing/benchmarking-guide.md
+105-0
1
+---
2
+title: Benchmarking Guide
3
+description: How to run and interpret JustAPI benchmarks.
4
+---
5
+
6
+## Setup
7
+
8
+```bash
9
+# Install benchmarking tools
10
+cargo install oha
11
+
12
+# Build the benchmark harness
13
+cargo build --release -p justapi-bench
14
+```
15
+
16
+## Running Benchmarks
17
+
18
+### Standard Workloads
19
+
20
+```bash
21
+# Build a baseline workload
22
+python benchmarks/workloads_justapi.py &
23
+oha -z 30s -c 100 http://localhost:8000/hello
24
+oha -z 30s -c 100 http://localhost:8000/echo
25
+```
26
+
27
+### CRUD Benchmarks (DB-backed)
28
+
29
+```bash
30
+# JustAPI vs FastAPI vs Robyn with SQLite
31
+bash benchmarks/run_crud_bench.sh
32
+```
33
+
34
+### Serialization Benchmarks
35
+
36
+```bash
37
+cargo run --release -p justapi-bench --bin justapi-bench
38
+```
39
+
40
+## Benchmark Protocol
41
+
42
+1. **Warm up**: Minimum 5 seconds before recording
43
+2. **Run**: 30 seconds, 100 concurrent connections
44
+3. **Repeat**: Minimum 3 runs per workload
45
+4. **Record**: p50, p95, p99 latency, RPS, peak RSS
46
+
47
+## Key Workloads
48
+
49
+| Name | Route | Method | Description |
50
+|---|---|---|---|
51
+| hello-world | `/hello` | GET | Static JSON response |
52
+| json-echo | `/echo` | POST | Nested JSON payload echoed |
53
+| db-sim | `/db` | GET | Simulated DB query (5ms sleep) |
54
+| native | `/native` | POST | Native fast path (724k+ RPS) |
55
+| crud-read | `/items` | GET | SQLite SELECT |
56
+| crud-write | `/items` | POST | SQLite INSERT |
57
+
58
+## Regression Gate
59
+
60
+A p99 regression >5% compared to the previous baseline **fails the benchmark gate**. The CI workflow (`bench.yml`) enforces this:
61
+
62
+```
63
+PR_RPS >= 0.95 * MAIN_RPS # Must pass
64
+```
65
+
66
+## Interpreting Results
67
+
68
+```
69
+Requests/sec: 701,234
70
+Latency:
71
+ p50: 0.07 ms
72
+ p95: 0.12 ms
73
+ p99: 0.19 ms
74
+```
75
+
76
+- **RPS**: Higher is better
77
+- **p50**: Typical latency (median)
78
+- **p99**: Worst-case latency (tail)
79
+- **Difference between p50 and p99**: Indicates latency consistency
80
+
81
+## Hardware Fixture
82
+
83
+Record the exact hardware when benchmarking:
84
+
85
+```
86
+CPU: 13th Gen Intel Core i5-13600K
87
+RAM: 31 GiB DDR5
88
+OS: CachyOS Linux
89
+Kernel: 6.x
90
+```
91
+
92
+Comparisons are only valid on the same hardware.
93
+
94
+## Adding New Benchmarks
95
+
96
+1. Add your workload to `benchmarks/workloads_*.py`
97
+2. Add a new workload entry in `BENCHMARKS.md`
98
+3. Run 3+ iterations and record all numbers
99
+4. Do **not** overwrite historical data — append
100
+
101
+## See Also
102
+
103
+- [Performance Tuning](/advanced/performance-tuning/) — Optimize your app
104
+- [BENCHMARKS.md](https://github.com/swadhinbiswas/JustAPI/blob/main/BENCHMARKS.md)
105
+- [Benchmark Harness Skill](/skills/benchmark-harness/SKILL.md)
0
106
▼docs_site/src/content/docs/contributing/coding-standards.md
+79-0
1
+---
2
+title: Coding Standards
3
+description: Conventions and guidelines for contributing to JustAPI.
4
+---
5
+
6
+## Rust-First Mandate
7
+
8
+If a feature **can** be implemented in Rust, it **must** be implemented in Rust. Python is reserved for:
9
+
10
+- Thin PyO3 re-exports (`from ._justapi import X`)
11
+- Translating Rust values to Python callables
12
+- User-facing helpers with no Rust equivalent
13
+
14
+The following **must live in Rust**:
15
+- Networking, sockets, TLS, connection management
16
+- HTTP/protocol parsing and response writing
17
+- Routing, middleware, rate-limiting, auth
18
+- Scheduling, worker/thread pools
19
+- (De)serialization of framework data
20
+- Hot paths: parsing, validation, buffering, compression
21
+
22
+## Commit Messages
23
+
24
+```
25
+<phase>: <what changed>
26
+```
27
+
28
+Examples:
29
+- `p3: add per-request arena allocator`
30
+- `p42: implement paged KV cache`
31
+
32
+One logical change per commit.
33
+
34
+## Branch Naming
35
+
36
+```
37
+phase-N/<short-description>
38
+```
39
+
40
+Examples:
41
+- `phase-42/paged-kv-cache`
42
+- `phase-51/scheduler-engine`
43
+
44
+## `unsafe` Code
45
+
46
+Every `unsafe` block must have a `// SAFETY:` comment explaining the invariant:
47
+
48
+```rust
49
+// SAFETY: The GIL is held, so the pointer is valid.
50
+let ptr = obj.as_ptr();
51
+```
52
+
53
+Whenever feasible, add a test that would fail if the invariant were violated.
54
+
55
+## Error Handling
56
+
57
+| Code Location | Error Type |
58
+|---|---|
59
+| Application code (CLI, bench) | `anyhow::Result` |
60
+| Library crates (core, py) | Typed `thiserror` |
61
+
62
+## Public API Changes
63
+
64
+All new public APIs require documentation (rustdoc or Python docstrings) before merge.
65
+
66
+## Pre-Submission Checklist
67
+
68
+- [ ] `cargo test --workspace` passes
69
+- [ ] `cargo clippy --workspace --tests -- -D warnings` clean
70
+- [ ] `cargo fmt --check` clean
71
+- [ ] `cargo miri test -p justapi-core` clean (if core touched)
72
+- [ ] Benchmarks appended to BENCHMARKS.md (no p99 regression >5%)
73
+- [ ] PLAN.md updated
74
+
75
+## See Also
76
+
77
+- [Development Setup](/contributing/development-setup/) — Get started
78
+- [Testing Guide](/contributing/testing-guide/) — Writing tests
79
+- [Documentation Guide](/contributing/documentation-guide/) — Writing docs
0
80
▼docs_site/src/content/docs/contributing/development-setup.md
+81-0
1
+---
2
+title: Development Setup
3
+description: Set up your local environment for JustAPI development.
4
+---
5
+
6
+## Prerequisites
7
+
8
+- Python 3.11+
9
+- Rust 1.85+ (install via [rustup](https://rustup.rs/))
10
+- Git
11
+
12
+## Clone the Repository
13
+
14
+```bash
15
+git clone https://github.com/swadhinbiswas/JustAPI.git
16
+cd JustAPI
17
+```
18
+
19
+## Python Environment
20
+
21
+```bash
22
+python -m venv .venv
23
+source .venv/bin/activate
24
+pip install maturin pydantic
25
+```
26
+
27
+## Build the Rust Extension
28
+
29
+```bash
30
+maturin develop --release --manifest-path crates/justapi-py/Cargo.toml
31
+```
32
+
33
+For debug builds (faster compile, slower runtime):
34
+
35
+```bash
36
+maturin develop --manifest-path crates/justapi-py/Cargo.toml
37
+```
38
+
39
+## Install CLI
40
+
41
+```bash
42
+cargo install --path crates/justapi-cli
43
+```
44
+
45
+## Install All Dependencies
46
+
47
+```bash
48
+# Rust
49
+cargo build --workspace
50
+
51
+# Python
52
+pip install -e ".[dev]"
53
+```
54
+
55
+## Editor Setup
56
+
57
+Recommended extensions:
58
+
59
+- **rust-analyzer** — Rust language support
60
+- **pyright** or **pylance** — Python language support
61
+- **maturin** — Python↔Rust integration
62
+
63
+## Running Tests
64
+
65
+```bash
66
+# Rust tests
67
+cargo test --workspace
68
+
69
+# Python tests
70
+pytest
71
+
72
+# Linting
73
+cargo clippy --workspace --tests -- -D warnings
74
+cargo fmt --check
75
+```
76
+
77
+## Next Steps
78
+
79
+- [Coding Standards](/contributing/coding-standards/) — Code conventions and guidelines
80
+- [Testing Guide](/contributing/testing-guide/) — How to write tests
81
+- [Benchmarking Guide](/contributing/benchmarking-guide/) — Performance testing
0
82
▼docs_site/src/content/docs/contributing/documentation-guide.md
+82-0
1
+---
2
+title: Documentation Guide
3
+description: How to contribute to the JustAPI documentation site.
4
+---
5
+
6
+## Tech Stack
7
+
8
+The documentation site is built with:
9
+
10
+- **Astro** 7.x — Static site generator
11
+- **Starlight** 0.41.x — Documentation theme
12
+- **Pagefind** — Full-text search
13
+- **Markdown/MDX** — Content format
14
+
15
+## Local Development
16
+
17
+```bash
18
+cd docs_site
19
+npm install
20
+npm run dev
21
+```
22
+
23
+The development server starts at `http://localhost:4321`.
24
+
25
+## Adding a New Page
26
+
27
+1. Create a `.md` or `.mdx` file in the appropriate directory under `src/content/docs/`
28
+2. Add frontmatter:
29
+
30
+```yaml
31
+---
32
+title: My New Page
33
+description: Brief description for SEO.
34
+---
35
+```
36
+
37
+3. If the page should appear in the sidebar, add it to `astro.config.mjs` in the `sidebar` array
38
+
39
+## Page Frontmatter
40
+
41
+| Field | Required | Description |
42
+|---|---|---|
43
+| `title` | Yes | Page title (also used in sidebar) |
44
+| `description` | Yes | Meta description for SEO |
45
+| `sidebar` | No | Custom sidebar label (defaults to title) |
46
+
47
+## Directory Structure
48
+
49
+```
50
+src/content/docs/
51
+├── index.mdx # Home page (splash layout)
52
+├── getting-started/ # Getting started guides
53
+├── tutorials/ # Step-by-step tutorials
54
+├── api-reference/ # API documentation
55
+├── advanced/ # Advanced guides
56
+├── deployment/ # Deployment guides
57
+├── security/ # Security documentation
58
+├── observability/ # Observability docs
59
+├── reference/ # Reference docs
60
+├── contributing/ # Contributor guides
61
+└── examples/ # Example gallery
62
+```
63
+
64
+## Conventions
65
+
66
+- Use `#` for page title (H1), `##` for sections (H2), `###` for subsections (H3)
67
+- Code blocks should specify language for syntax highlighting: ` ```python `
68
+- Use relative links to other docs pages: `[Text](/getting-started/overview/)`
69
+- All code examples should be tested before committing
70
+
71
+## Building
72
+
73
+```bash
74
+npm run build # Output in dist/
75
+npm run preview # Preview the built site
76
+```
77
+
78
+## See Also
79
+
80
+- [Development Setup](/contributing/development-setup/) — Get started
81
+- [Coding Standards](/contributing/coding-standards/) — Code conventions
82
+- [Testing Guide](/contributing/testing-guide/) — Writing tests
0
83
▼docs_site/src/content/docs/contributing/testing-guide.md
+152-0
1
+---
2
+title: Testing Guide
3
+description: How to write and run tests for JustAPI.
4
+---
5
+
6
+## Running Tests
7
+
8
+```bash
9
+# All Rust tests
10
+cargo test --workspace
11
+
12
+# Single crate
13
+cargo test -p justapi-core
14
+
15
+# Python tests
16
+pytest
17
+
18
+# Miri (unsafe validation)
19
+cargo +nightly miri test -p justapi-core
20
+```
21
+
22
+## Writing Rust Tests
23
+
24
+Unit tests go at the bottom of the module they test:
25
+
26
+```rust
27
+#[cfg(test)]
28
+mod tests {
29
+ use super::*;
30
+
31
+ #[test]
32
+ fn test_normalize_db_url() {
33
+ assert_eq!(normalize_db_url("sqlite:///foo.db"), "sqlite:foo.db");
34
+ assert_eq!(normalize_db_url("sqlite:////tmp/foo.db"), "sqlite:/tmp/foo.db");
35
+ }
36
+}
37
+```
38
+
39
+## Writing Python Tests
40
+
41
+Use the `JustAPITestClient` for in-process testing:
42
+
43
+```python
44
+from justapi import JustAPIApp, JustAPITestClient
45
+
46
+
47
+def test_hello_world():
48
+ app = JustAPIApp()
49
+
50
+ @app.get("/hello")
51
+ def hello(request):
52
+ return {"message": "Hello!"}
53
+
54
+ client = JustAPITestClient(app)
55
+ response = client.get("/hello")
56
+
57
+ assert response.status == 200
58
+ assert response.json() == {"message": "Hello!"}
59
+```
60
+
61
+### Testing POST Endpoints
62
+
63
+```python
64
+def test_create_item():
65
+ app = JustAPIApp()
66
+
67
+ @app.post("/items")
68
+ def create(request):
69
+ data = request.json()
70
+ return {"id": 1, **data}
71
+
72
+ client = JustAPITestClient(app)
73
+ response = client.post("/items", body={"name": "Widget", "price": 9.99})
74
+
75
+ assert response.status == 200
76
+ assert response.json()["name"] == "Widget"
77
+```
78
+
79
+### Testing Errors
80
+
81
+```python
82
+def test_404():
83
+ app = JustAPIApp()
84
+ client = JustAPITestClient(app)
85
+ response = client.get("/nonexistent")
86
+ assert response.status == 404
87
+```
88
+
89
+## Integration Testing
90
+
91
+For integration tests that need a running server:
92
+
93
+```python
94
+# tests/test_app.py
95
+from justapi import JustAPIApp
96
+
97
+app = JustAPIApp()
98
+
99
+@app.get("/health")
100
+def health(request):
101
+ return {"status": "ok"}
102
+```
103
+
104
+Then use `JustAPITestClient` for end-to-end flow tests.
105
+
106
+## Property-Based Testing
107
+
108
+Use `proptest` for Rust property-based tests:
109
+
110
+```rust
111
+use proptest::prelude::*;
112
+
113
+proptest! {
114
+ #[test]
115
+ fn test_route_roundtrip(path in ".*") {
116
+ // Property: route matching should never panic
117
+ let router = Router::new();
118
+ // ...
119
+ }
120
+}
121
+```
122
+
123
+## Test File Layout
124
+
125
+```
126
+tests/
127
+├── test_annotations.py
128
+├── test_middleware.py
129
+├── test_responses.py
130
+├── test_multipart.py
131
+├── test_exceptions.py
132
+├── test_db_concurrent.py
133
+└── ...
134
+```
135
+
136
+## CI Testing
137
+
138
+Every PR runs:
139
+
140
+1. `cargo test --workspace`
141
+2. `cargo clippy -- -D warnings`
142
+3. `cargo fmt --check`
143
+4. `cargo miri test -p justapi-core`
144
+5. `pytest` (Python 3.12 + free-threaded 3.14t)
145
+6. `cargo audit`
146
+7. Fuzz tests (7 targets, 60s each)
147
+
148
+## See Also
149
+
150
+- [Development Setup](/contributing/development-setup/) — Get started
151
+- [Coding Standards](/contributing/coding-standards/) — Code conventions
152
+- [Testing Client API](/api-reference/testing-client/) — `JustAPITestClient` reference
0
153