Skip to content

spike: feasibility study for build-time OpenAPI codegen #97

Description

@MaxMichel2

Part of #72

Depends on #73 being stable and shipped (this spike needs a real parser and a real spec size to measure against, not a hypothetical one).

Summary

Feasibility study — not an implementation commitment — into compiling the OpenAPI spec into typed Kotlin at build time (a Gradle plugin, KotlinPoet-generated commonMain sources) instead of parsing it on-device at runtime. Output is a written yes/no recommendation with measured numbers and an effort estimate, not code.

Why this is worth studying

The proven KMP precedent is SQLDelight: .sq files are compiled to typed Kotlin at build time, and the runtime library never parses SQL or does reflection — it just calls generated, typed functions. The same shape applied here: openapi.yaml → Gradle plugin → generated commonMain Kotlin objects → devview-networkmock-core's runtime engine reads plain compiled data, zero on-device parsing.

Potential benefits, to be measured rather than assumed:

  • Performance: no YAML/JSON parsing cost at app startup (see feat: OpenAPI 3.x spec loader (JSON + YAML) #73's own concern about parsing a large spec — this would eliminate it as opposed to just hedging it).
  • Compile-time validation: a malformed spec fails the build with a clear error, rather than surfacing as a runtime Result.failure an integrator might not notice until they open the debug drawer.
  • Type-safe autocomplete: integrators could reference generated constants (e.g. GeneratedSpec.GET_USER_PROFILE) from their own test setups instead of stringly-typed operation ids.

Why this is a spike, not a commitment

A Gradle plugin generating correct commonMain sources across Android + iOS targets, that plays well with Gradle/IDE sync, is comparable effort to the parser built in #73 — this is the same category of KMP-tooling risk #73 already has to navigate for kaml (do the tools actually work uniformly across all targets), now applied to build tooling instead of a runtime dependency. It should not be built speculatively before #73 has shipped and proven whether runtime parsing is actually a measured problem in practice, as opposed to a theoretical one.

What "done" looks like for this spike

  • A small proof-of-concept Gradle task (does not need to be a publishable plugin) that reads a representative OpenAPI spec and generates a commonMain Kotlin file via KotlinPoet.
  • Measured numbers: parse time for a realistic large spec (a few hundred operations) via feat: OpenAPI 3.x spec loader (JSON + YAML) #73's runtime parser, compared to zero (build-time approach pays this cost once, at build time, not per app launch).
  • A written assessment: is the runtime parsing cost from feat: OpenAPI 3.x spec loader (JSON + YAML) #73 actually a problem in practice (get a real number, not a guess), and does the Gradle-plugin complexity/maintenance cost look worth paying to eliminate it?
  • Explicitly note in the writeup: this axis (build-time vs. runtime parsing) is independent of how many input formats exist — if the deferred "minimal JSON frontend" issue is ever picked up, it's a separate question whether that frontend also feeds this same build-time pipeline or gets its own runtime parser; don't conflate the two decisions in this spike.

Acceptance criteria

  • A working (not necessarily polished) build-time codegen proof-of-concept exists, applied to at least one representative spec.
  • Measured parse-time numbers are recorded for comparison.
  • A written recommendation (yes/no/not-yet) with reasoning, posted to this issue or linked from it.
  • No production code changes are required by this issue — it either closes with "not worth it now" or spins off a properly-scoped follow-up implementation issue.

Files likely touched

None in production code. Proof-of-concept work likely lives in a scratch module or a branch, not merged as-is.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions