{"id":51385543,"url":"https://github.com/dicklesworthstone/fastapi_rust","last_synced_at":"2026-07-03T20:01:06.590Z","repository":{"id":333843494,"uuid":"1138658114","full_name":"Dicklesworthstone/fastapi_rust","owner":"Dicklesworthstone","description":"Rust web framework inspired by Python's FastAPI: type-safe routing, zero-copy parsing, OpenAPI generation, and structured concurrency via asupersync","archived":false,"fork":false,"pushed_at":"2026-06-29T02:08:11.000Z","size":3605,"stargazers_count":19,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T04:04:54.957Z","etag":null,"topics":["api","async","openapi","rust","web-framework"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dicklesworthstone.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-21T00:34:38.000Z","updated_at":"2026-06-29T02:08:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"58c8cf3f-7c03-4e7a-a8ab-66aeea03d0a6","html_url":"https://github.com/Dicklesworthstone/fastapi_rust","commit_stats":null,"previous_names":["dicklesworthstone/fastapi_rust"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Dicklesworthstone/fastapi_rust","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Ffastapi_rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Ffastapi_rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Ffastapi_rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Ffastapi_rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dicklesworthstone","download_url":"https://codeload.github.com/Dicklesworthstone/fastapi_rust/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dicklesworthstone%2Ffastapi_rust/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35099548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-03T02:00:05.635Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","async","openapi","rust","web-framework"],"created_at":"2026-07-03T20:00:48.671Z","updated_at":"2026-07-03T20:01:06.580Z","avatar_url":"https://github.com/Dicklesworthstone.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fastapi_rust\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"fastapi_rust_illustration.webp\" alt=\"fastapi_rust - High-performance Rust web framework with FastAPI-inspired ergonomics\"\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n**High-performance Rust web framework with FastAPI-inspired ergonomics**\n\n*A Rust port inspired by [tiangolo/fastapi](https://github.com/tiangolo/fastapi) (Python), extended with [asupersync](https://github.com/Dicklesworthstone/asupersync) for structured concurrency, zero-copy parsing, and deterministic testing.*\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Rust](https://img.shields.io/badge/rust-1.85+-orange.svg)](https://www.rust-lang.org/)\n[![Status](https://img.shields.io/badge/status-early%20development-yellow.svg)]()\n\n*Type-safe routing | Zero-copy parsing | Structured concurrency | OpenAPI generation*\n\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003ch3\u003eQuick Install\u003c/h3\u003e\n\n```bash\ncurl -fsSL \"https://raw.githubusercontent.com/Dicklesworthstone/fastapi_rust/main/install.sh?$(date +%s)\" | bash\n```\n\n**Or add to your project:**\n\n```toml\n# Cargo.toml\n[dependencies]\nfastapi = { git = \"https://github.com/Dicklesworthstone/fastapi_rust.git\" }\nasupersync = { git = \"https://github.com/Dicklesworthstone/asupersync.git\" }\nserde = { version = \"1\", features = [\"derive\"] }\n```\n\n\u003cp\u003e\u003cem\u003eRequires Rust 1.85+ (2024 edition). Co-developed with \u003ca href=\"https://github.com/Dicklesworthstone/asupersync\"\u003easupersync\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n---\n\n## TL;DR\n\n**The Problem**: Rust web frameworks either sacrifice developer ergonomics for performance (raw `hyper`) or hide allocations behind layers of abstraction (Axum + Tower). None leverage structured concurrency for cancel-correct request handling, and most require a massive dependency tree.\n\n**The Solution**: fastapi_rust brings FastAPI's intuitive, type-driven API design to Rust with zero-copy HTTP parsing, compile-time route validation, and first-class integration with [asupersync](https://github.com/Dicklesworthstone/asupersync) for structured concurrency and deterministic testing.\n\n### Why fastapi_rust?\n\n| Feature | What It Does |\n|---------|--------------|\n| **Zero-copy HTTP parsing** | Requests parsed directly from buffers; no allocations on fast paths |\n| **Compile-time route validation** | Invalid routes fail at build time via proc macros, not at runtime |\n| **Structured concurrency** | Request handlers run in regions; cancellation is automatic and correct |\n| **Type-driven extractors** | Declare parameter types; framework extracts and validates automatically |\n| **Dependency discipline** | No Tokio/Hyper/Tower/Axum; direct deps kept small with a bias toward removal |\n| **Deterministic testing** | Lab runtime for reproducible concurrent request tests |\n| **FastAPI-compatible errors** | Validation errors match FastAPI's JSON format exactly |\n\n---\n\n## Quick Example\n\n```rust\nuse fastapi_rust::prelude::*;\n\n#[derive(Serialize, Deserialize, JsonSchema)]\nstruct Item {\n    id: i64,\n    name: String,\n    price: f64,\n}\n\n#[get(\"/items/{id}\")]\nasync fn get_item(cx: \u0026Cx, id: Path\u003ci64\u003e) -\u003e Json\u003cItem\u003e {\n    cx.checkpoint()?;  // Cancellation-safe yield point\n\n    Json(Item {\n        id: id.0,\n        name: \"Widget\".into(),\n        price: 29.99,\n    })\n}\n\n#[post(\"/items\")]\nasync fn create_item(cx: \u0026Cx, item: Json\u003cItem\u003e) -\u003e Response {\n    // Automatic JSON deserialization with validation\n    // Wrong Content-Type -\u003e 415\n    // Parse error -\u003e 422 with detailed location\n    // Payload too large -\u003e 413\n    Response::created().json(\u0026item.0)\n}\n\n#[get(\"/search\")]\nasync fn search(\n    cx: \u0026Cx,\n    q: Query\u003cSearchParams\u003e,           // ?q=...\u0026limit=...\n    auth: Header\u003cOption\u003cBearer\u003e\u003e,     // Optional auth header\n) -\u003e Result\u003cJson\u003cResults\u003e, HttpError\u003e {\n    // All extraction happens automatically\n    // Wrong types -\u003e compile error\n    // Missing required -\u003e 422 response\n}\n\nfn main() {\n    let app = App::builder()\n        .title(\"My API\")\n        .version(\"1.0.0\")\n        .route_entry(get_item_route())\n        .route_entry(create_item_route())\n        .route_entry(search_route())\n        .middleware(RequestIdMiddleware::new())\n        .middleware(Cors::permissive())\n        .build();\n\n    // Run with asupersync\n    let rt = asupersync::runtime::RuntimeBuilder::current_thread()\n        .build()\n        .expect(\"runtime must build\");\n    rt.block_on(async move {\n        serve(app, \"0.0.0.0:8000\")\n            .await\n            .expect(\"server must start\");\n    });\n}\n```\n\n---\n\n## Design Philosophy\n\n### 1. Extract Spec, Never Translate\n\nWe study FastAPI's behavior and ergonomics, then implement idiomatically in Rust. No line-by-line Python translation - Rust has better tools for these problems:\n\n- Python decorators -\u003e Rust procedural macros\n- Pydantic validation -\u003e Compile-time type checking + serde\n- ASGI lifecycle -\u003e Structured concurrency regions\n- Runtime reflection -\u003e Compile-time code generation\n\n### 2. Zero-Cost Abstractions\n\n| Technique | Implementation |\n|-----------|----------------|\n| No runtime reflection | Proc macros analyze types at compile time |\n| No trait objects on hot paths | Monomorphization via generics |\n| Pre-allocated buffers | 4KB default, configurable per-route |\n| Zero-copy HTTP parsing | Borrowed types reference request buffer |\n| Inline critical paths | `#[inline(always)]` on hot code |\n\n### 3. Cancel-Correct by Default\n\nEvery request handler runs in an asupersync **region**. Client disconnects, timeouts, and shutdowns trigger graceful cancellation:\n\n```\nConnection Accepted\n    |\n    v\n+-----------------------------------------------+\n|  Request Region (owns all request work)       |\n|  +-------------------------------------------+|\n|  |  Handler Task                             ||\n|  |  +-- Dependency Task (DB query)           ||\n|  |  +-- Dependency Task (cache lookup)       ||\n|  |  +-- Background Task (logging)            ||\n|  +-------------------------------------------+|\n|                                               |\n|  Region close waits for ALL tasks to finish  |\n+-----------------------------------------------+\n    |\n    v\nResponse Sent (only after region quiescent)\n```\n\n**No orphaned tasks.** Client disconnect -\u003e cancel region -\u003e all tasks cleaned up.\n\n### 4. Dependency Discipline\n\n| Crate | Purpose | Why |\n|-------|---------|-----|\n| `asupersync` | Async runtime | Our own - cancel-correct, capability-secure |\n| `serde` | Serialization traits | Zero-cost, industry standard |\n| `serde_json` | JSON parsing | Fast, well-optimized |\n\n**Explicitly avoided:** Tokio, Hyper, Axum, Tower, and runtime-reflection/schema-building crates.\n\nNote: Some workspace crates currently use additional small utility/test/proc-macro dependencies\nwhere it meaningfully improves safety or developer experience. Shrinking this further is an active\ngoal tracked in Beads (see `bd-uz2s`).\n\n---\n\n## How fastapi_rust Compares\n\n| Feature | fastapi_rust | Axum | Actix-web | Rocket |\n|---------|--------------|------|-----------|--------|\n| Zero-copy HTTP parsing | **Custom** | Hyper | Partial | No |\n| Compile-time routes | **Proc macros** | Runtime | Runtime | Macros |\n| Structured concurrency | **asupersync** | Tokio spawn | Actix-rt | Tokio |\n| Cancel-correct shutdown | **Native** | Manual | Manual | Manual |\n| Dependency injection | **Native + cache** | State only | Data only | Managed |\n| OpenAPI generation | **Compile-time** | External | External | External |\n| Deterministic testing | **Lab runtime** | No | No | No |\n| Direct deps (core runtime crates) | **Low (single digits)** | ~80+ | ~60+ | ~50+ |\n| FastAPI-style errors | **Yes (422 format)** | No | No | No |\n\n### When to Use fastapi_rust\n\n- You need cancel-correct request handling (graceful shutdown, timeouts)\n- You want compile-time route validation\n- You're building with asupersync for structured concurrency\n- You want deterministic tests for concurrent code\n- You're familiar with FastAPI and want similar ergonomics in Rust\n\n### When to Consider Alternatives\n\n- You need production-proven stability today (fastapi_rust is v0.1.2)\n- You require production-hardened WebSocket support (basic support exists; full parity tracked in `bd-z09e`)\n- You have existing Tokio-based infrastructure\n- You need the massive ecosystem of Tower middleware\n\n---\n\n## Installation\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nfastapi_rust = { package = \"fastapi-rust\", version = \"0.1.2\" }\nasupersync = \"0.1.1\"\nserde = { version = \"1\", features = [\"derive\"] }\n```\n\n**Note**: The crates.io package is `fastapi-rust`, and the crate name is `fastapi_rust`.\n\n### From Source\n\n```bash\ngit clone https://github.com/Dicklesworthstone/fastapi_rust.git\ncd fastapi_rust\ncargo build --release\n```\n\n### Requirements\n\n- **Rust 1.85+** (2024 edition)\n- **[asupersync](https://github.com/Dicklesworthstone/asupersync)** (co-developed runtime)\n\n---\n\n## Architecture\n\n```\n+-------------------------------------------------------------------+\n|                       fastapi_rust (facade)                        |\n|   Re-exports all public types, prelude module                      |\n+-------------------------------------------------------------------+\n        |           |           |           |           |\n        v           v           v           v           v\n+-----------+ +-----------+ +-----------+ +-----------+ +-----------+\n|   core    | |   http    | |  router   | |  macros   | |  openapi  |\n|           | |           | |           | |           | |           |\n| - Request | | - Parser  | | - Trie    | | - #[get]  | | - Schema  |\n| - Response| | - Body    | | - Match   | | - #[post] | | - Builder |\n| - Context | | - Query   | | - Registry| | - Derive  | | - Spec    |\n| - Extract | | - Headers | |           | |           | |           |\n| - Depends | | - Writer  | |           | |           | |           |\n| - Error   | | - Server  | |           | |           | |           |\n| - Middle. | | - Stream  | |           | |           | |           |\n| - Logging | |           | |           | |           | |           |\n| - Testing | |           | |           | |           | |           |\n| - Shutdown| |           | |           | |           | |           |\n+-----------+ +-----------+ +-----------+ +-----------+ +-----------+\n        |\n        v\n+-------------------------------------------------------------------+\n|                         asupersync                                 |\n|   Structured concurrency - Cx - Regions - Budgets - Lab           |\n+-------------------------------------------------------------------+\n```\n\n### Crate Overview\n\n| Crate | ~Lines | Purpose |\n|-------|--------|---------|\n| `fastapi_rust` | 100 | Facade: re-exports, prelude |\n| `fastapi-core` | 6,000 | Request, Response, extractors, DI, middleware, logging, testing, shutdown |\n| `fastapi-http` | 2,500 | Zero-copy HTTP/1.1 parser, body handling, query parsing, streaming |\n| `fastapi-router` | 600 | Radix trie routing, path matching, conflict detection |\n| `fastapi-macros` | 400 | `#[get]`, `#[post]`, `#[derive(Validate)]`, `#[derive(JsonSchema)]` |\n| `fastapi-openapi` | 500 | OpenAPI 3.1 types, schema builder, spec generation |\n\n---\n\n## Extractors\n\nExtract typed data from requests declaratively:\n\n```rust\nuse fastapi_rust::prelude::*;\n\n#[get(\"/users/{id}\")]\nasync fn get_user(\n    cx: \u0026Cx,                           // Capability context (required)\n    id: Path\u003ci64\u003e,                     // Path parameter: /users/123\n    q: Query\u003cSearchParams\u003e,            // Query string: ?q=...\u0026limit=...\n    auth: Header\u003cAuthorization\u003e,       // Required header\n    accept: Header\u003cOption\u003cAccept\u003e\u003e,    // Optional header\n) -\u003e Result\u003cJson\u003cUser\u003e, HttpError\u003e {\n    // Types declare what you need - framework handles extraction\n    // Wrong types -\u003e compile error\n    // Missing required -\u003e 422 with FastAPI-compatible error\n}\n\n#[post(\"/items\")]\nasync fn create(\n    cx: \u0026Cx,\n    item: Json\u003cCreateItem\u003e,            // JSON body\n) -\u003e Result\u003cResponse, HttpError\u003e {\n    // 415 if wrong Content-Type\n    // 413 if payload too large (configurable)\n    // 422 if parse error (with location path)\n}\n```\n\n### Available Extractors\n\n| Extractor | Description | Error Response |\n|-----------|-------------|----------------|\n| `Path\u003cT\u003e` | URL path parameters | 422 if missing/wrong type |\n| `Query\u003cT\u003e` | Query string | 422 if missing/invalid |\n| `Json\u003cT\u003e` | JSON request body | 415/413/422 |\n| `Header\u003cT\u003e` | Single header value | 422 if missing/invalid |\n| `HeaderValues\u003cT\u003e` | All values for header | 422 if invalid |\n| `State\u003cT\u003e` | Application state | 500 if not configured |\n| `Depends\u003cT\u003e` | Dependency injection | Depends on factory |\n| `Option\u003cT\u003e` | Any extractor, optional | Never fails |\n\n---\n\n## Middleware\n\nComposable middleware with onion model execution:\n\n```rust\nuse fastapi_rust::prelude::*;\n\n// Built-in middleware\nlet app = App::builder()\n    .middleware(RequestIdMiddleware::new())      // Add X-Request-Id\n    .middleware(RequestResponseLogger::default()) // Log all requests\n    .middleware(Cors::permissive())               // CORS handling\n    .middleware(RequireHeader::new(\"X-API-Key\")) // Require header\n    .middleware(AddResponseHeader::new(\"X-Powered-By\", b\"fastapi_rust\"))\n    .build();\n\n// Custom middleware\nstruct Timing;\n\nimpl Middleware for Timing {\n    async fn before(\u0026self, ctx: \u0026RequestContext, req: \u0026mut Request) -\u003e ControlFlow {\n        // Store start time in context\n        ControlFlow::Continue\n    }\n\n    async fn after(\u0026self, ctx: \u0026RequestContext, req: \u0026Request, mut resp: Response) -\u003e Response {\n        // Add X-Response-Time header\n        resp\n    }\n}\n```\n\n### Execution Order\n\n```\nRequest -\u003e MW1.before -\u003e MW2.before -\u003e MW3.before -\u003e Handler\n                                                        |\nResponse \u003c- MW1.after \u003c- MW2.after \u003c- MW3.after \u003c- Response\n```\n\nFirst registered runs first on the way in, last on the way out (onion model).\n\n---\n\n## Dependency Injection\n\nRequest-scoped dependencies with caching:\n\n```rust\nuse fastapi_rust::prelude::*;\n\n// Define a dependency\n#[derive(Clone)]\nstruct DatabasePool { /* ... */ }\n\nimpl FromDependency for DatabasePool {\n    type Error = HttpError;\n\n    async fn from_dependency(ctx: \u0026RequestContext, req: \u0026mut Request) -\u003e Result\u003cSelf, HttpError\u003e {\n        // Resolved once per request, cached for subsequent uses\n        Ok(DatabasePool::connect().await?)\n    }\n}\n\n// Use in handler\n#[get(\"/users/{id}\")]\nasync fn get_user(\n    cx: \u0026Cx,\n    id: Path\u003ci64\u003e,\n    db: Depends\u003cDatabasePool\u003e,  // Automatically resolved and cached\n) -\u003e Result\u003cJson\u003cUser\u003e, HttpError\u003e {\n    let user = db.fetch_user(id.0).await?;\n    Ok(Json(user))\n}\n\n// Override for testing\nlet overrides = DependencyOverrides::new()\n    .with::\u003cDatabasePool\u003e(MockDatabase::new());\n```\n\n### Dependency Scopes\n\n| Scope | Behavior |\n|-------|----------|\n| `Request` (default) | Resolve once, cache for request lifetime |\n| `Function` | Resolve on every extraction |\n| `NoCache` | Explicit opt-out of caching |\n\n---\n\n## Testing\n\nIn-process testing without network I/O:\n\n```rust\nuse fastapi_rust::testing::*;\n\n#[test]\nfn test_get_item() {\n    let client = TestClient::new(app);\n\n    let resp = client.get(\"/items/42\")\n        .header(\"Authorization\", \"Bearer token\")\n        .send();\n\n    assert_eq!(resp.status(), 200);\n\n    let item: Item = resp.json();\n    assert_eq!(item.id, 42);\n}\n\n#[test]\nfn test_deterministic() {\n    // Same seed = same execution order for concurrent operations\n    let client = TestClient::with_seed(app, 12345);\n\n    // Reproducible even with concurrent handlers\n    let resp = client.post(\"/items\")\n        .json(\u0026new_item)\n        .send();\n\n    assert_eq!(resp.status(), 201);\n}\n\n#[test]\nfn test_with_overrides() {\n    let overrides = DependencyOverrides::new()\n        .with::\u003cDatabase\u003e(MockDatabase::new());\n\n    let client = TestClient::new(app)\n        .with_overrides(overrides);\n\n    // Handler receives MockDatabase instead of real one\n}\n```\n\n### Assertion Helpers\n\n```rust\nuse fastapi_core::{assert_status, assert_header, assert_json};\n\nassert_status!(resp, 200);\nassert_header!(resp, \"Content-Type\", \"application/json\");\nassert_json!(resp, {\"id\": 42, \"name\": \"Widget\"});\n```\n\n---\n\n## Error Handling\n\nFastAPI-compatible validation errors:\n\n```rust\n// Handler returns HttpError\n#[get(\"/items/{id}\")]\nasync fn get_item(id: Path\u003ci64\u003e) -\u003e Result\u003cJson\u003cItem\u003e, HttpError\u003e {\n    if id.0 \u003c 0 {\n        return Err(HttpError::unprocessable_entity()\n            .detail(\"ID must be positive\")\n            .loc([\"path\", \"id\"]));\n    }\n    // ...\n}\n```\n\n**Error response format (FastAPI-compatible):**\n\n```json\n{\n  \"detail\": [\n    {\n      \"type\": \"value_error\",\n      \"loc\": [\"path\", \"id\"],\n      \"msg\": \"ID must be positive\",\n      \"input\": -1\n    }\n  ]\n}\n```\n\n### Built-in Error Types\n\n| Status | Constructor | Use Case |\n|--------|-------------|----------|\n| 400 | `HttpError::bad_request()` | Malformed request |\n| 401 | `HttpError::unauthorized()` | Missing/invalid auth |\n| 403 | `HttpError::forbidden()` | Permission denied |\n| 404 | `HttpError::not_found()` | Resource not found |\n| 413 | `HttpError::payload_too_large()` | Body exceeds limit |\n| 415 | `HttpError::unsupported_media_type()` | Wrong Content-Type |\n| 422 | `HttpError::unprocessable_entity()` | Validation failed |\n| 500 | `HttpError::internal()` | Server error |\n\n---\n\n## Graceful Shutdown\n\nCancel-correct shutdown with configurable grace periods:\n\n```rust\nuse fastapi_rust::prelude::*;\nuse fastapi_core::shutdown::*;\n\nlet app = App::builder()\n    .graceful_shutdown(GracefulConfig {\n        grace_period: Duration::from_secs(30),\n        force_timeout: Duration::from_secs(5),\n    })\n    .on_shutdown(|phase| async move {\n        match phase {\n            ShutdownPhase::GracePeriod =\u003e {\n                // Stop accepting new connections\n                // Wait for in-flight requests\n            }\n            ShutdownPhase::ForceClose =\u003e {\n                // Cancel remaining requests\n            }\n        }\n        Ok(())\n    })\n    .build();\n```\n\nShutdown propagates through asupersync regions - no orphaned tasks.\n\n---\n\n## Configuration\n\n```rust\nuse fastapi_rust::prelude::*;\n\n\tlet app = App::builder()\n\t    // Metadata\n\t    .title(\"My API\")\n\t    .version(\"1.0.0\")\n\t    .description(\"A sample API built with fastapi_rust\")\n\n\t    // Routes\n\t    .route_entry(get_item_route())\n\t    .route_entry(create_item_route())\n\t    .route_entry(delete_item_route())\n\n    // Middleware (order matters)\n    .middleware(RequestIdMiddleware::new())\n    .middleware(Cors::new(CorsConfig {\n        allow_origins: vec![\"https://example.com\".into()],\n        allow_methods: vec![Method::Get, Method::Post],\n        allow_headers: vec![\"Authorization\".into()],\n        max_age: Some(3600),\n    }))\n\n    // Shared state\n    .state(DatabasePool::new())\n    .state(CacheClient::new())\n\n    // Exception handlers\n    .exception_handler(|err: DatabaseError| {\n        HttpError::internal().detail(err.to_string())\n    })\n\n    // Lifecycle hooks\n    .on_startup(|| async {\n        println!(\"Starting up...\");\n        Ok(())\n    })\n    .on_shutdown(|_| async {\n        println!(\"Shutting down...\");\n        Ok(())\n    })\n\n    // Build\n    .build();\n```\n\n---\n\n## Troubleshooting\n\n### Common Issues\n\n| Problem | Cause | Solution |\n|---------|-------|----------|\n| `asupersync not found` | Missing dependency | Add `asupersync` to Cargo.toml |\n| `Cx lifetime error` | Holding Cx across await | Use `cx.checkpoint()` pattern |\n| Route conflicts | Overlapping path patterns | Check for `{param}` vs literal conflicts |\n| 422 on valid JSON | Missing `#[derive(Deserialize)]` | Add serde derive to your types |\n| Middleware not running | Wrong registration order | Check middleware ordering |\n\n### Debugging Tips\n\n```rust\n// Enable request logging\n.middleware(RequestResponseLogger::new(LogConfig {\n    log_bodies: true,\n    log_headers: true,\n}))\n\n// Check route registration\napp.routes().for_each(|r| println!(\"{} {}\", r.method, r.path));\n\n// Deterministic test reproduction\nTestClient::with_seed(app, failing_seed)\n```\n\n---\n\n## Parity Status (Goal: 100% FastAPI Coverage)\n\nThis project is intended to reach **100% feature-for-feature, behavior-for-behavior parity** with\nthe legacy Python FastAPI library.\n\nCurrent parity status and the concrete gap list are tracked in:\n- `PROPOSED_RUST_ARCHITECTURE.md` (Section 0: Parity Matrix)\n- Beads (`br ready`, `br show \u003cid\u003e`) with the top-level epic `bd-uz2s`\n\n### Known Gaps (As Of 2026-02-11)\n\n- **OpenAPI generation**: currently minimal; needs real operation/schema mapping from route metadata.\n- **TCP server integration/hardening**: `fastapi-http` has a server implementation, but the end-to-end\n  surface is still evolving.\n- **WebSockets**: partial (handshake + basic frames). Full FastAPI/Starlette parity is tracked in `bd-z09e`.\n- **Multipart/form-data + file uploads**: parser + `MultipartForm` extractor + incremental streamed-body parsing +\n  streamed-part incremental flushing + spool-backed file parts + `UploadFile` async API (`read`/`write`/`seek`/`close`) are implemented.\n  Remaining parity work in `bd-3ess` is mainly API-surface refinement around fully streamed consumption paths and broader behavior parity edge cases.\n- **HTTP/2**: missing (`bd-2c9t`).\n\n### Non-Negotiables / Constraints\n\n- **Requires asupersync**: no Tokio support (by design).\n- **Rust 1.85+**: uses Rust 2024 edition features.\n- **Early development**: API will change before v1.0.\n\n---\n\n## FAQ\n\n### Why \"fastapi_rust\"?\n\nIt's a Rust web framework inspired by Python's [FastAPI](https://fastapi.tiangolo.com/), preserving the type-driven API design while achieving native performance and cancel-correctness.\n\n### Why not use Tokio/Axum?\n\nTokio's spawn model makes cancel-correctness difficult - tasks can outlive their scope, leading to resource leaks and subtle bugs. asupersync's structured concurrency ensures all request-related work completes or cancels together.\n\n### Can I use this in production?\n\nNot production-ready yet. This is v0.1.2 in active development; the TCP server exists (built on `asupersync::net`),\nbut parity and production hardening are tracked under `bd-uz2s`.\n\n### How fast is it?\n\nWe haven't published end-to-end benchmarks yet, but the architecture is designed for:\n- Zero allocations on the fast path\n- Zero-copy request parsing\n- No runtime reflection\n- Pre-allocated buffers (4KB default)\n\n### Does it support async/await?\n\nYes, fully. All handlers, middleware, and extractors are async-native, built on asupersync's structured concurrency model.\n\n### Why the minimal dependency approach?\n\nEach dependency is a maintenance burden, security surface, and compile-time cost. By keeping dependencies small and intentional, we:\n- Reduce build times significantly\n- Have full control over behavior\n- Avoid dependency conflicts\n- Make auditing practical\n\n### How do validation errors compare to FastAPI?\n\nIdentical format. The same client code that handles FastAPI 422 responses will work with fastapi_rust:\n\n```json\n{\n  \"detail\": [\n    {\"type\": \"missing\", \"loc\": [\"body\", \"email\"], \"msg\": \"Field required\"}\n  ]\n}\n```\n\n---\n\n## About Contributions\n\nPlease don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other \"stakeholders,\" which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via `gh` and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.\n\n---\n\n## License\n\nMIT license. See [LICENSE](LICENSE).\n\n---\n\n## Related Projects\n\n| Project | Description |\n|---------|-------------|\n| [asupersync](https://github.com/Dicklesworthstone/asupersync) | Structured concurrency async runtime (co-developed) |\n| [FastAPI](https://fastapi.tiangolo.com/) | The Python framework that inspired this project |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdicklesworthstone%2Ffastapi_rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdicklesworthstone%2Ffastapi_rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdicklesworthstone%2Ffastapi_rust/lists"}