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.

2.6 KiB

+++ title = "[TRIAGE] OpenAPI spec serving strategy — embed YAML at compile time vs load at runtime" priority = 7 status = "done" ticket_type = "task" dependencies = [] +++

This is a triage decision ticket. It must be resolved before dependent implementation tickets can proceed. OpenAPI spec serving strategy: should the spec be embedded at compile time (include_str! macro) or loaded at runtime from a file or generated programmatically? 1. **Compile-time embed** — `include_str!("../../api/openapi.yaml")` bakes the YAML into the binary. Simple, no runtime file I/O needed for Workers. 2. **Runtime load** — read the file at startup. Does not work in Cloudflare Workers (no filesystem). 3. **Programmatic generation** — use a crate like `utoipa` to generate the spec from handler annotations. Most maintainable but adds complexity. **Chosen approach: Option 1 — compile-time embed, via `build.rs` (not raw `include_str!` of YAML).**

The refined implementation uses a build.rs script rather than embedding the raw YAML and parsing it at runtime. Specifically:

  • build.rs reads api/openapi.yaml, parses it to serde_json::Value with serde_yaml, writes compact JSON to $OUT_DIR/openapi.json, and emits cargo:rerun-if-changed=api/openapi.yaml so the conversion re-runs on every spec change.
  • The GET /api/ handler serves the result as: const OPENAPI_JSON: &str = include_str!(concat!(env!("OUT_DIR"), "/openapi.json"));
  • serde_yaml is a [build-dependencies] entry only — it never enters the Workers binary, keeping binary size minimal.
  • Zero runtime overhead: no OnceLock, no lazy parsing, no heap allocation for the spec.

Options 2 (runtime load) and 3 (utoipa) were ruled out:

  • Option 2 is impossible on Cloudflare Workers — there is no filesystem at runtime.
  • Option 3 (utoipa) would require annotating all 7 handlers with macros and migrating away from the hand-written api/openapi.yaml spec, which is already complete and validated. The added complexity is not justified for a project of this size.

Tickets updated:

  • 8892d5 (new): implements build.rs and adds [build-dependencies] to Cargo.toml.
  • 28e7d9: updated with the concrete include_str!(concat!(env!("OUT_DIR"), "/openapi.json")) handler pattern; now depends on 8892d5 instead of this triage ticket.
  • 1f5bb5: updated with the [build-dependencies] constraint.
  • f3dc74 (API sub-project): 8892d5 added as dependency.
`chore(quotesdb): resolve triage — openapi-spec-serving-strategy-embed-yaml-at-compile-time-vs-`