Skip to content

Path parameters defined in request.params not exported to OpenAPI spec parameters array #286

@TheJACKedViking

Description

@TheJACKedViking

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 the id parameter
  • ✅ TypeScript types are correctly inferred from the Zod schema
  • ❌ OpenAPI spec's parameters array 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.params but 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

  1. Is this intended behavior, or is path parameter export expected to work?
  2. If it's a bug, is it something you'd be interested in fixing?
  3. If it's an architectural limitation, are there configuration options we're missing?
  4. 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:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions