Repository navigation
Decide the openapi-generator relationship and 0.2 maintenance plan before merging the pure-Julia rewrite (#103) #104
Description
Context
#103 replaces the 0.2.x runtime-library model with a pure-Julia pipeline: OpenAPI.client / OpenAPI.server parse OAS 3.0/3.1/3.2 documents and emit generated modules directly, with no involvement from the openapi-generator Java toolchain. Today, however, this package's primary consumers are modules produced by openapi-generator's julia-client / julia-server targets, whose templates call the public 0.2.x runtime API (OpenAPI.Clients, OpenAPI.Servers, validate_param, property_type, …) — an API that #103 removes entirely.
This issue is to decide, before merge/tag, what happens to that lane. It is not a proposal to change the direction of #103 — the rewrite has been evaluated in depth against real workloads (including a full Kubernetes-client trial across 27 group documents) and the new pipeline wins on merit for 3.x work.
Evaluation status caveat: that depth applies to the client side. Server generation is present and symmetric (OpenAPI.server / serverplan, a register!(router, impl) contract deliberately shaped like the 0.2.x target's register, HTTP.Router support via OpenAPIHTTPExt, and a server_source seam for other frameworks) and has a substantial test suite — but it has not been exercised against a live production-shaped service the way the client was. A smoke test implementing one real spec (e.g. a JuliaHub runner spec) end to end should happen before the server path is declared ready.
Why we should not try to bridge the two generators
The obvious "integration" — retargeting the openapi-generator mustache templates to emit #103-style code — is structurally unworkable:
- Generated modules embed
_SPECdata and compiled schema information produced by the normalize→plan pipeline and the JSON Schema engine. Mustache templates render the JavaCodegenModel; reproducing this would mean reimplementingnormalize.jl+planning.jlin Java. - The fidelity gains are precisely where templates are weakest: the Java generator collapses
oneOf/anyOftovalue::Any, emits hand-picked per-constraint validation call sites, and only wires parameter styling for query parameters. Pure-julia OpenAPI internals rewrite #103 produces typed unions and full schema-driven validation. - OAS coverage has inverted: openapi-generator's 3.1 support is incomplete upstream, while Pure-julia OpenAPI internals rewrite #103 handles 3.0/3.1/3.2 natively (and passes the official JSON Schema suite). The one capability moving the other way is Swagger 2.0 input, which openapi-generator converts internally and Pure-julia OpenAPI internals rewrite #103's loader rejects.
A shell-out from the Java generator to Julia is against openapi-generator's pure-JVM architecture and would not be accepted upstream.
Proposal: clean split, with the legacy lane explicitly maintained
- Create a
release-0.2maintenance branch before v1 is tagged. The openapi-generator targets, and every package currently built on them, keep tracking the 0.2.x runtime; recent fixes like fix(client): discard truncated JSON document on mid-stream EOF #97–fix(client): :http streaming stalls small chunks until 8KB buffer fills #102 show this lane still needs a home for backports. - One housekeeping PR to openapi-generator: document that
julia-client/julia-servertrack OpenAPI.jl 0.2.x and point Julia-native users atOpenAPI.client/OpenAPI.server; delete the staledocs/generators/julia.md(advertises an unregisteredjuliagenerator); fix theexportOperationsconfig bug inJuliaClientCodegen.java(the flag writes throughexportModels, so the two options aren't separable). - Update this repo's README/CONTRIBUTING, which currently route codegen contributions to the openapi-generator repo.
Release blockers to resolve before tagging 1.0
- Compat breakage for existing generated code. The Julia targets emit no
Project.toml, so openapi-generator'ssamples-julia.yamlCI and any fresh environment doingPkg.add("OpenAPI")against legacy generated code will resolve to 1.x and fail on the missingOpenAPI.Clients. Options: pinOpenAPI = "0.2"in that workflow and have the upstream generator emit a compat'dProject.toml; or release the rewrite under a new package name. Worth deciding deliberately rather than discovering via broken CI. - The generated-module ↔ runtime contract is private. Generated modules import and extend
OpenAPI.Runtimeinternals (_decode/_encode), so they are version-coupled to the exact OpenAPI release that generated them. That's acceptable policy for baked artifacts, but it should be documented, and a small public surface (e.g.decode(Module, T, json)) would soften it — once 1.0 tags, this contract freezes. - Documentation generation is missing. The openapi-generator lane emits per-model and per-API markdown (
docs/*.md) plus a usageREADME.md; Pure-julia OpenAPI internals rewrite #103 emits none of that. Generated client operations do get Julia docstrings (signature + specsummary+METHOD /path), but models get no docstrings at all — schema and propertydescriptionfields from the spec are dropped entirely, and in large specs those descriptions are most of the documentation value. Two asks, both cheap relative to the pipeline work already done: carrydescriptionthrough to model/field docstrings at emission time, and offer a markdown-docs emitter as a separate function over the sameClientPlan. At minimum the first should land before 1.0; otherwise this freezes into the "what the native path doesn't do" list. - State the remaining dropped capabilities. Relative to the openapi-generator lane: no Swagger 2.0 input (document "convert first"), no user-overridable templates, single-file emit instead of per-model/per-API files, and no runtime-fix-without-regeneration. All defensible — but they should be release-notes content, not surprises.
Nice-to-have
- Adopt openapi-generator's petstore/sample corpus as additional conformance fixtures — it encodes a decade of weird-spec regressions and Pure-julia OpenAPI internals rewrite #103 already has external-corpus test infrastructure.
Activity
quinnj commentedon Aug 17, 2026
This all sounds like a good plan + reasonable things to do pre-1.0 release.
feat(codegen): contract guard, version stamp, reorder-proof dialects,…
tanmaykm commentedon Aug 27, 2026
Status update (2026-08-27)
The runtime-contract and docstring blockers were addressed on the #103 branch (details). I verified the claims against the PR head (
8124eec) directly — regenerated a sample client/server pair, loaded them, and exercised the failure paths — rather than taking the summary at face value. Everything checked out.Blocker-by-blocker
1. Compat breakage for existing generated code — OPEN. Untouched by the PR, deliberately: the 0.2 compat pin for
samples-julia.yaml, the upstreamProject.tomlemission, and cuttingrelease-0.2are decisions for this repo and openapi-generator, not for #103. Therelease-0.2branch cut is the most time-sensitive item on this whole list — it gets harder with every commit tomain.2. Generated-module ↔ runtime contract — RESOLVED, via the "private by policy, guarded" route:
Runtime.CONTRACT_VERSION(currently 3) plusRuntime.require_contract(version, generator); both documented as permanently frozen names.server_module_sourceextension path) stamps the producing OpenAPI.jl version in its banner and calls the guard at load time, before the privateimport OpenAPI.Runtime:list — verified live: a stale module fails with an actionable "regenerate" error naming both versions and both contract numbers.Dialectliterals (standard dialects emit asSchemaEngine.dialect(:draft202012)lookups; custom ones use a keyword-only constructor),Runtime.Speckeywords are required, and a tripwire test pinsCONTRACT_VERSIONso shape changes without a bump fail CI.decode(Module, T, json)— was not built, so every future contract bump forces downstream regeneration. Coherent, but worth stating explicitly since 1.0 freezes it.3. Documentation generation — MINIMUM MET. Spec
descriptions now flow into generated model docstrings (schema description plus a bullet per documented field) and operation docstrings (summary,METHOD /path, parameter/request-body bullets), for both client and server output. Hostile-content tests cover quotes,$,""", backslashes, and unicode, and generated output remains byte-deterministic. Verified live on a sample spec.The second ask — a markdown-docs emitter over
ClientPlan(thedocs/*.mdequivalent of the openapi-generator lane) — was not built. It should either get its own post-1.0 issue or be consciously dropped into the MIGRATION.md dropped-capabilities list; otherwise it silently freezes into "what the native path doesn't do", which is exactly what this issue warned about.4. Dropped capabilities stated — RESOLVED.
MIGRATION.mdnow covers the 0.2.x → 1.0 transition: the openapi-generator lane, client/server API mapping, dropped capabilities, and generated-artifact compatibility.Remaining before tag, in suggested order
release-0.2from currentmain(time-sensitive, zero cost).samples-julia.yaml.docs/and the docdeploy workflow entirely, sogh-pageswill keep serving 0.2 documentation for an API that no longer exists. Needs either a Documenter setup for the new API or a deliberate teardown/redirect.julia.md,exportOperationsfix).tanmaykm commentedon Aug 27, 2026
Cut
release-0.2frommainatd4471f3(== v0.2.8): https://github.com/JuliaComputing/OpenAPI.jl/tree/release-0.2. The branch runs CI on push, and its README/CONTRIBUTING now state that 0.2.x fixes target it whilemainhosts the 1.x rewrite. Item 1 of the proposal is done; remaining on the compat blocker is thesamples-julia.yamlpin / upstreamProject.tomlemission decision.tanmaykm commentedon Aug 27, 2026
Upstream housekeeping PR opened: OpenAPITools/openapi-generator#24789 — emits a compat'd
Project.tomlfrom both Julia generators (resolving the compat-breakage blocker at the source, per the decision above), repointssamples-julia.yamlfrom thev0.2.0tag torelease-0.2, fixes theexportOperationsconfig bug, documents the 0.2.x runtime boundary in generated READMEs, and deletes the staledocs/generators/julia.md. That completes item 2 of the proposal; the compat blocker closes when it merges.tanmaykm commentedon Aug 29, 2026
Stock-take before merging #103 (2026-08-27)
All four release blockers are now resolved:
Project.tomlpinningOpenAPI = "0.2", andsamples-julia.yamltests againstrelease-0.2(green on the PR twice and on the post-merge master push).Proposal items:
release-0.2cut ✔, upstream housekeeping PR merged ✔, README/CONTRIBUTING routing updated onrelease-0.2(and #103 replaces both onmain) ✔.Still recommended before tagging v1.0.0 (from this issue's own caveat + review notes):
docs/and the docdeploy job, so the site will keep serving 0.2 docs against a 1.x package; needs a redirect/teardown or a minimal Documenter site at merge time.SHAis in Pure-julia OpenAPI internals rewrite #103's[deps]without a[compat]entry (the other stdlibs have one) — worth adding before registration to keep AutoMerge happy.#103 itself is mergeable, up to date with
main(includes v0.2.8), CI green (Julia 1.10, Julia 1, corpus),version = "1.0.0", same package UUID.Pure-julia OpenAPI internals rewrite (#103)
tanmaykm commentedon Aug 29, 2026
Server smoke test complete — all five findings from the live validation are fixed and up for review:
main): typed-parameter double decode (petstorefindByStatusreturned 400 on every call), buffered sequential-JSON array-vs-item handling, undocumented-success operations now answeringnothingwith an empty 200 plus a:missing_success_responseplanning warning, and permissive-mode tolerance for externally declared security schemes (strict still rejects). Validated by the full suite plus live petstore (same-lane and cross-lane with the unmodified 0.2 client), gap fixtures, and the unmodified JuliaHub secrets document end to end.release-0.2): the 0.2 client now serializes form-style CSV query parameters with literal separator commas per the OAS Style Examples/RFC6570, restoring interop with 1.x generated servers. Full 0.2 suite green with live servers (3080 tests); suggest tagging v0.2.9 on merge.With these merged, the caveat on the server path is discharged; remaining before the v1.0.0 tag are only the gh-pages docs cleanup and the
SHAcompat entry.tanmaykm commentedon Aug 29, 2026
Docs update: #109 adds the Documenter manual for the 1.0 line (option A from the docs discussion) — 12-page manual, API reference with enforced public-name coverage, build-time-executed examples, CI deploy job, and a trimmed README. Also noted while investigating:
gh-pagescurrently serves v0.1.23 asstableand has no v0.2.x versioned docs at all (tag-triggered deploys silently stopped after v0.1.23); the preview deploy on #107 just succeeded, so the deploy key itself works. Merging #109 revivesdev, and tagging v1.0.0 / v0.2.9 will publish versioned docs and movestablecorrectly.tanmaykm commentedon Sep 2, 2026
Closing (2026-09-02)
Everything this issue set out to decide is done, and all four release blockers are verified against the live repo state:
MIGRATION.md.release-0.2cut and v0.2.9 tagged from it; upstream housekeeping PR merged; README onmainroutes 0.2.x users torelease-0.2andMIGRATION.md.devon gh-pages serves the 1.0 manual.Two loose ends found while verifying, neither a blocker:
push: tagstrigger in CI never ran for v1.0.0 or v0.2.9 (zero workflow runs on either ref) and gh-pagesstablestill pointed at v0.1.23. This is also the root cause of the "deploys silently stopped after v0.1.23" observation above. Fixed today by re-pushing both tags from a user account (same tag objects, same commits) and re-publishing the GitHub releases that the tag re-push had reverted to drafts. Tag CI runs are in progress for v1.0.0 and v0.2.9; their docs jobs will publish versioned docs and movestable. Future tags will hit the same problem unless TagBot's ssh push actually triggers workflows — worth checking on the next release.SHAhas no[compat]entry inProject.tomlonmain. Cosmetic (stdlib; AutoMerge passed).Nice-to-have (openapi-generator sample corpus as conformance fixtures) was not adopted and can get its own issue if wanted.