Skip to content

openapi: add register_routes option to disable spec-path route registration#249

Merged
intel352 merged 4 commits intomainfrom
copilot/add-register-routes-option
Mar 3, 2026
Merged

openapi: add register_routes option to disable spec-path route registration#249
intel352 merged 4 commits intomainfrom
copilot/add-register-routes-option

Conversation

Copy link
Contributor

Copilot AI commented Mar 3, 2026

  • Add RegisterRoutes *bool field to OpenAPIConfig struct in module/openapi.go
  • Modify OpenAPIModule.RegisterRoutes to skip spec-path route registration when register_routes: false
  • Update plugin factory in plugins/openapi/plugin.go to parse register_routes config key
  • Update schema definitions in schema/module_schema.go to include register_routes field
  • Add tests for the new register_routes: false behavior in module/openapi_test.go
  • Add max_body_bytes to built-in openapi module schema in schema/module_schema.go for parity with plugin schema
Original prompt

This section details on the original issue you should resolve

<issue_title>openapi module: add register_routes option to disable spec-path route registration</issue_title>
<issue_description>## Problem

The openapi module type registers HTTP routes for every path in the OpenAPI spec, regardless of whether x-pipeline is set. These routes are registered during the wiring hook phase (priority 45), before pipeline triggers register their routes during Start().

This means that when both an openapi module and pipeline triggers define the same path (e.g., GET /forms):

  1. OpenAPI module registers the route first (wiring hook phase)
  2. Pipeline trigger tries to register the same route → silently dropped by HTTPRouter.AddRoute duplicate check
  3. The path is now handled by the OpenAPI stub handler, which returns 501 Not Implemented (since no x-pipeline is set)

This makes it impossible to use the openapi module purely for documentation (serving /openapi.json, /openapi.yaml, and Swagger UI at /docs) alongside existing pipeline-trigger-based routing.

Proposed Solution

Add a register_routes config option (default true for backward compatibility):

modules:
  - name: api-docs
    type: openapi
    dependsOn: [api-router]
    config:
      spec_file: ./specs/my-api.yaml
      register_routes: false    # NEW: only serve spec endpoints, don't register API routes
      swagger_ui:
        enabled: true
        path: /docs

When register_routes: false:

  • Still parse the spec and serve it at /openapi.json and /openapi.yaml
  • Still serve Swagger UI at the configured path
  • Do NOT register routes from spec.Paths on the router
  • Pipelines continue to handle all API routes via their own triggers

This enables a gradual migration path: teams can start with docs-only mode, then progressively add x-pipeline to operations and set register_routes: true when ready.

Workaround

Currently the only workaround is to not load the openapi plugin at all, which means losing the built-in spec serving and Swagger UI functionality.

🤖 Generated with Claude Code</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…th route registration

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Copilot AI changed the title [WIP] Add register_routes option to disable spec-path route registration openapi: add register_routes option to disable spec-path route registration Mar 3, 2026
@intel352 intel352 marked this pull request as ready for review March 3, 2026 20:37
Copilot AI review requested due to automatic review settings March 3, 2026 20:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a register_routes option to the openapi module so it can run in “docs-only” mode (serve /openapi.json, /openapi.yaml, and Swagger UI) without pre-registering stub handlers for every spec path, avoiding route conflicts with pipeline-trigger routing.

Changes:

  • Introduces OpenAPIConfig.RegisterRoutes *bool and gates spec-path route registration on it (nil/true = current behavior; false = skip).
  • Exposes register_routes in the OpenAPI plugin factory + module schema (with default true for backward compatibility).
  • Adds unit tests covering register_routes=false and nil default behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
module/openapi.go Adds config field + conditional to skip spec-path route registration when disabled.
module/openapi_test.go Adds tests for register_routes=false and nil defaulting to true.
plugins/openapi/plugin.go Parses register_routes from config and adds it to the plugin’s module schema + defaults.
schema/module_schema.go Adds register_routes to the built-in module schema registry with default config.

{Key: "router", Label: "Router Module", Type: FieldTypeString, Description: "Name of the http.router module to register routes on (auto-detected if omitted)", Placeholder: "my-router"},
{Key: "register_routes", Label: "Register Routes", Type: FieldTypeBool, DefaultValue: true, Description: "When false, skip registering spec-path routes (only serve spec endpoints and Swagger UI); default true"},
{Key: "validation", Label: "Validation", Type: FieldTypeJSON, DefaultValue: map[string]any{"request": true, "response": false}, Description: "Request/response validation settings, e.g. {\"request\": true, \"response\": false}"},
{Key: "swagger_ui", Label: "Swagger UI", Type: FieldTypeJSON, DefaultValue: map[string]any{"enabled": false, "path": "/docs"}, Description: "Swagger UI settings, e.g. {\"enabled\": false, \"path\": \"/docs\"}"},
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The built-in OpenAPI ModuleSchema in this registry still doesn’t include the max_body_bytes config field, even though the OpenAPI module config struct and the OpenAPI plugin schema support it. This creates a divergence between built-in schema-driven tooling/validation and the plugin-provided schema/UI; consider adding max_body_bytes here for parity (and an appropriate DefaultValue if desired).

Suggested change
{Key: "swagger_ui", Label: "Swagger UI", Type: FieldTypeJSON, DefaultValue: map[string]any{"enabled": false, "path": "/docs"}, Description: "Swagger UI settings, e.g. {\"enabled\": false, \"path\": \"/docs\"}"},
{Key: "swagger_ui", Label: "Swagger UI", Type: FieldTypeJSON, DefaultValue: map[string]any{"enabled": false, "path": "/docs"}, Description: "Swagger UI settings, e.g. {\"enabled\": false, \"path\": \"/docs\"}"},
{Key: "max_body_bytes", Label: "Max Body Bytes", Type: FieldTypeNumber, Description: "Maximum allowed request body size in bytes for validated OpenAPI operations (leave empty to use module default)", Placeholder: "1048576"},

Copilot uses AI. Check for mistakes.
@intel352
Copy link
Contributor

intel352 commented Mar 3, 2026

@copilot apply changes based on the comments in this thread

…with plugin schema

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 3, 2026

@copilot apply changes based on the comments in this thread

Done in cdad61b — added max_body_bytes to the built-in openapi schema in schema/module_schema.go to match the plugin-provided schema.

@intel352 intel352 merged commit 67faeab into main Mar 3, 2026
14 checks passed
@intel352 intel352 deleted the copilot/add-register-routes-option branch March 3, 2026 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

openapi module: add register_routes option to disable spec-path route registration

3 participants