-
Notifications
You must be signed in to change notification settings - Fork 63
Description
Path parameters defined in request.params not exported to OpenAPI spec parameters array
Problem Description
When defining path parameters via request.params in an OpenAPIRoute class, Chanfana correctly validates them at runtime but does not export them to the generated OpenAPI spec's parameters array. This causes issues for tools that consume the OpenAPI spec, particularly TypeScript client generators like Orval.
Minimal Reproduction
Route Definition:
import { OpenAPIRoute } from 'chanfana'
import { z } from 'zod'
export class GetUser extends OpenAPIRoute {
schema = {
tags: ['Users'],
summary: 'Get user by ID',
request: {
params: z.object({
id: z.string().describe('User ID'),
}),
},
responses: {
200: {
description: 'User found',
content: {
'application/json': {
schema: z.object({
id: z.string(),
name: z.string(),
}),
},
},
},
},
}
async handle(c) {
const { id } = c.req.valid('params')
// Runtime validation works correctly
return c.json({ id, name: 'John Doe' })
}
}OpenAPI Spec Generated (excerpt):
{
"paths": {
"/users/{id}": {
"get": {
"tags": ["Users"],
"summary": "Get user by ID",
"parameters": [], // ❌ Empty - path parameter not exported
"responses": {
"200": {
"description": "User found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" }
}
}
}
}
}
}
}
}
}
}Expected Behavior
The OpenAPI spec should include the path parameter definition:
{
"paths": {
"/users/{id}": {
"get": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"description": "User ID",
"schema": {
"type": "string"
}
}
]
}
}
}
}Actual Behavior
- ✅ Runtime validation works correctly -
c.req.valid('params')properly validates theidparameter - ✅ TypeScript types are correctly inferred from the Zod schema
- ❌ OpenAPI spec's
parametersarray is empty or omits path parameters - ❌ Tools consuming the OpenAPI spec (like Orval, OpenAPI Generator) don't know about path parameters
- ❌ Generated TypeScript clients don't include path parameters in function signatures
Context & Impact
Why This Matters:
- Frontend teams use tools like Orval to generate type-safe API clients from OpenAPI specs
- Without path parameter definitions, generated clients are incomplete
- Developers must manually patch generated code or post-process the OpenAPI spec
- OpenAPI documentation is incomplete (path parameters don't appear in Swagger UI)
Observed Behavior:
- Query parameters (
request.query) export correctly ✅ - Body parameters (
request.body) export correctly ✅ - Path parameters (
request.params) do NOT export ❌
Scale: In our project, this affects 24+ API operations across 4 microservices.
Potential Root Cause
Based on research:
- Chanfana delegates OpenAPI conversion to
@asteasolutions/zod-to-openapi - That library can export path parameters, but requires explicit
.openapi({ param: { ... } })metadata - Chanfana creates Zod schemas for
request.paramsbut doesn't appear to add the necessary metadata - This may be an integration gap between Chanfana and zod-to-openapi
Workaround
We've implemented a post-processing script that parses path patterns and injects missing parameter definitions:
// Extract path parameters from URL pattern
const expectedParams = path.match(/\{([^}]+)\}/g)
// Add missing parameters to OpenAPI spec
operation.parameters = [
...existingParams,
...missingParams.map(name => ({
name,
in: 'path',
required: true,
schema: { type: 'string' }
}))
]This works but adds build complexity and can't infer types from Zod schemas.
Environment
- Chanfana version: v2.8.3
- Runtime: Cloudflare Workers
- Framework: Hono
- TypeScript: 5.9+
- Zod: 4.1+
Questions
- Is this intended behavior, or is path parameter export expected to work?
- If it's a bug, is it something you'd be interested in fixing?
- If it's an architectural limitation, are there configuration options we're missing?
- Would a PR be welcome if we develop a generic fix?
Additional Notes
Thank you for maintaining Chanfana - it's been invaluable for our Cloudflare Workers architecture. We're happy to contribute if there's interest in fixing this upstream. In the meantime, our workaround is stable and working for our use case.
References:
- zod-to-openapi param documentation: https://github.com/asteasolutions/zod-to-openapi#parameters
- Related zod-to-openapi issues: Fix property content type wrongfully appearing in response schema #137, Bump husky from 9.1.6 to 9.1.7 #198, Bump the dev-deps group across 1 directory with 6 updates #218 (show param metadata challenges)