Auto-generating OpenAPI from server routes — does this fit the roadmap, and should it flow through middleware? #7530
tombeckenham
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hey all 👋 — I've been building a public HTTP API on Start and kept reaching for an OpenAPI spec (typed SDKs, a docs UI, cross-language clients). There's no way to produce one from server routes today, so I dug into the types to understand why, and I think it's surprisingly close. Wanted to float it as an idea and get maintainer/community read on direction before anyone writes code.
Why server routes seem like the right source
Server functions are awkward for OpenAPI — opaque RPC URLs, seroval-framed bodies (not plain JSON). Server routes are the opposite: real REST paths + methods already live in the route tree, and they're raw
Request/Response(JSON). And the router plugin already walks the whole tree at build to emitrouteTree.gen.ts— so emitting anopenapi.jsonin the same pass feels natural. The only thing missing is the schemas.What I found is missing
{ context, request, params, pathname, next }, so yourequest.json()+ parse by hand and the request shape is invisible to any generator. (The method builder is{ handler }only — looks like an intentional extension point.)RequestMiddlewarehas noinputValidator, even thoughFunctionMiddlewaredoes (FunctionMiddlewareValidator) and those validators intersect across the chain (IntersectAllMiddleware). Routes feel like the asymmetric primitive here.response/output schema to describe responses.The "should it be middleware?" question
This is really what I'd love input on. Given function middleware already composes validators, my instinct is that the request side should flow through middleware too — i.e. give
RequestMiddlewaretheinputValidatorthatFunctionMiddlewarealready has, so routes compose the same way:That also opens a nice door: auth middleware declaring a security scheme once, so every route in its chain inherits
securityin the spec:The one thing that feels not like middleware is the response contract — that seems to belong on the method:
Then the build pass collects routes with validators/responses + middleware security schemes and emits OpenAPI via Zod v4's
z.toJSONSchema()(Standard Schema, so Valibot/ArkType too);$id→{id}.The constraint I keep bumping into
Middleware can only carry the spec if the schema is declarative metadata (
inputValidator/securitySchemeas builder fields the plugin reads without running.server()). Anything validated imperatively inside.server()is invisible to a generator. So whatever shape this takes, the spec-bearing parts probably need to stay declarative.Questions for the group
inputValidatoronRequestMiddlewarealign with where middleware is heading — and is the slot shape ({ body, query, path, headers }) the right call, given HTTP locations don't exist in the server-fn validator model?validateSearchfeedparameters[in:query]so there aren't two query mechanisms?Related I found: #3608 (cross-language type codegen), #5129 (consuming OpenAPI via
openapi-fetch), #7315 (validator→inputValidatorrename). Happy to prototype the build-pass + a worked example (I have a real/api/v1to dogfood) if there's appetite. Curious what folks think — especially on the middleware angle.Beta Was this translation helpful? Give feedback.
All reactions