You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.4 KiB
Markdown
68 lines
2.4 KiB
Markdown
+++
|
|
title = "Implement GET /api/ — serve OpenAPI spec as JSON"
|
|
priority = 5
|
|
status = "todo"
|
|
ticket_type = "task"
|
|
dependencies = ["1f5bb5", "8892d5"]
|
|
+++
|
|
|
|
<context>
|
|
The `quotesdb` API is built with Axum + Tokio, targeting Cloudflare Workers via `workers-rs`. It serves JSON at `/api/*` endpoints and persists data to Cloudflare D1 (production) or a local SQLite file via Turso (development). Source lives in `src/bin/api/`.
|
|
|
|
Shared types and utilities are in `src/lib.rs` — code placed there must compile for both the host target and `wasm32-unknown-unknown`.
|
|
|
|
The `GET /api/` endpoint serves the OpenAPI 3.1.0 specification as JSON. This endpoint requires no authentication and is the entry point for API documentation and client generation.
|
|
</context>
|
|
|
|
<goal>
|
|
Implement the `GET /api/` handler that returns the OpenAPI spec as `application/json`.
|
|
|
|
Strategy resolved in TRIAGE 2ec8b1: **compile-time embed via `build.rs`** (ticket 8892d5).
|
|
The `build.rs` converts `api/openapi.yaml` to JSON at build time and writes it to
|
|
`$OUT_DIR/openapi.json`. The handler serves this as a static `&str`:
|
|
|
|
```rust
|
|
// Embedded at compile time by build.rs — no runtime parsing, no serde_yaml in binary.
|
|
const OPENAPI_JSON: &str = include_str!(concat!(env!("OUT_DIR"), "/openapi.json"));
|
|
|
|
pub async fn get_openapi_spec() -> impl IntoResponse {
|
|
(
|
|
[(axum::http::header::CONTENT_TYPE, "application/json")],
|
|
OPENAPI_JSON,
|
|
)
|
|
}
|
|
```
|
|
|
|
Register the route in the Axum router as `GET /api/`.
|
|
</goal>
|
|
|
|
<constraints>
|
|
- The response `Content-Type` must be `application/json`.
|
|
- Do NOT use `serde_yaml` in this handler — the YAML→JSON conversion is done by `build.rs`
|
|
(ticket 8892d5). The handler only serves a pre-built static string.
|
|
- Do NOT use `OnceLock` or lazy parsing — `OPENAPI_JSON` is a `const &str` embedded at
|
|
compile time; no initialisation is needed.
|
|
- The spec at `api/openapi.yaml` is the source of truth — validate with
|
|
`redocly lint api/openapi.yaml` after any changes.
|
|
</constraints>
|
|
|
|
<skills>
|
|
Use `superpowers:test-driven-development` — write a test that hits `GET /api/` and asserts the response is valid JSON with an `openapi` key.
|
|
Use `superpowers:verification-before-completion` before closing.
|
|
</skills>
|
|
|
|
<validation>
|
|
Run in order from the `quotesdb/` directory:
|
|
|
|
```sh
|
|
cargo fmt
|
|
cargo check
|
|
cargo clippy
|
|
cargo test
|
|
```
|
|
</validation>
|
|
|
|
<commit>
|
|
`feat(quotesdb): implement GET /api/ to serve OpenAPI spec as JSON`
|
|
</commit>
|