GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Register handlers in spec order by mromaszewicz · Pull Request #2465 · oapi-codegen/oapi-codegen

Conversation

@mromaszewicz

@mromaszewicz mromaszewicz commented Jul 13, 2026

Copy link
Copy Markdown
Member

Closes: #1887

Route registration was emitted in sorted path order, so reordering paths in the spec had no effect. On routers that match in registration order (Fiber, Gorilla/mux) this left users no way to disambiguate overlapping paths — e.g. a request for /templates/privates/shortcuts always went to /templates/privates/{id} rather than /templates/{visibility}/shortcuts.

kin-openapi stores paths in a map, losing declaration order at parse time, so enable its origin tracking (Loader.IncludeOrigin) to recover each path's source line onto the OperationDefinition (SpecOrder). Each GenerateXServer now renders its registration template with operations sorted by SpecOrder, via a new GenerateTemplatesIntoBuffer that composes passes into one buffer (GenerateTemplates wraps it).

Model and interface generation are intentionally left in the old sorted order to preserve any existing ordering behavior — in particular the order-dependent fallback in name-collision resolution. Only handler registration follows spec order.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

greptile-apps[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@mromaszewicz @claude
Register handlers in spec order
6ae9824
Closes: oapi-codegen#1887

Route registration was emitted in sorted path order, so reordering paths in
the spec had no effect. On routers that match in registration order (Fiber,
Gorilla/mux) this left users no way to disambiguate overlapping paths — e.g.
a request for `/templates/privates/shortcuts` always went to
`/templates/privates/{id}` rather than `/templates/{visibility}/shortcuts`.

kin-openapi stores paths in a map, losing declaration order at parse time,
so enable its origin tracking (`Loader.IncludeOrigin`) to recover each
path's source line onto the OperationDefinition (SpecOrder). Each
GenerateXServer now renders its registration template with operations sorted
by SpecOrder, via a new GenerateTemplatesIntoBuffer that composes passes into
one buffer (GenerateTemplates wraps it).

Model and interface generation are intentionally left in the old sorted
order to preserve any existing ordering behavior — in particular the
order-dependent fallback in name-collision resolution. Only handler
registration follows spec order.

Co-Authored-By: Claude Fable 5 <[email protected]>
@mromaszewicz
mromaszewicz requested a review from a team as a code owner July 13, 2026 18:11
@mromaszewicz mromaszewicz added bug Something isn't working notable changes Used for release notes to highlight these more highly labels Jul 13, 2026
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes issue #1887 by making route registration follow the path declaration order in the OpenAPI spec rather than sorted alphabetical order. On routers that match in registration order (Fiber, Gorilla/mux) this gives users direct control over precedence between overlapping paths.

  • pkg/util/loader.go: enables IncludeOrigin = true so kin-openapi records each path's source line; OperationDefinition gains a SpecOrder int populated from pathItem.Origin.Key.Line.
  • pkg/codegen/operations.go: refactors all GenerateXServer functions to use the new GenerateTemplatesIntoBuffer helper, feeding sortOperationsBySpecOrder(operations) only to the registration template while leaving interface/middleware generation in the existing sorted order.
  • internal/test/servers/routeorder/: new Fiber integration test that verifies /templates/privates/shortcuts dispatches to the earlier-declared {visibility}/shortcuts route rather than the later-declared privates/{id} route.

Confidence Score: 4/5

Safe to merge with minor follow-up; the core logic is sound and well-tested, but the route-registration order change is unconditional and will cause all existing generated files to diff on the next make generate run.

The implementation is correct — sortOperationsBySpecOrder makes a defensive copy, uses a stable sort, and handles the all-zero fallback cleanly. All nine router backends are updated in parallel, the new test directory follows the prescribed layout, and the generated fixtures show the expected ordering. The two open questions are: a misplaced godoc and whether the unconditional ordering change should be gated behind a compat flag.

pkg/codegen/operations.go — the doc comment placement and the compat-flag question both live here.

Important Files Changed

Filename Overview
pkg/codegen/operations.go Core logic change: adds SpecOrder field to OperationDefinition, pathItemSourceLine helper, sortOperationsBySpecOrder, and GenerateTemplatesIntoBuffer. All GenerateXServer functions updated to pass spec-ordered ops to their registration template. One doc comment is misplaced and the unconditional behavior change warrants a compat-flag discussion.
pkg/util/loader.go Adds loader.IncludeOrigin = true to both LoadSwagger and the inner loader in LoadSwaggerWithOverlay to enable per-path source-line tracking. Straightforward and correct.
pkg/codegen/operations_spec_order_test.go New unit tests for sortOperationsBySpecOrder covering spec-line ordering, stability within a shared path, all-zero fallback, and no-mutation guarantee.
internal/test/servers/routeorder/routeorder_test.go New Fiber integration test verifying spec-order routing fix. Correctly placed under internal/test/servers/.
internal/test/servers/routeorder/spec.yaml New minimal spec with two overlapping paths ordered to exercise spec-declaration-order routing.
internal/test/servers/routeorder/routeorder.gen.go Generated Fiber server; RegisterHandlersWithOptions correctly registers TemplateShortcutGetAll before PrivateTemplateGet, matching spec declaration order.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
pkg/codegen/operations.go:1069-1074
**Misplaced godoc comment**

The line `// OperationDefinitions returns all operations for a swagger definition.` (originally the godoc for `OperationDefinitions`) is now the *first line* of `pathItemSourceLine`'s doc comment block. As a result, `go doc` will show `pathItemSourceLine` as starting with "OperationDefinitions returns all operations for a swagger definition.", and `OperationDefinitions` itself (line 1081) has no godoc at all. The `OperationDefinitions` comment line should be moved back to immediately precede `OperationDefinitions`, with a blank line separating the two function doc blocks.

### Issue 2 of 2
pkg/codegen/operations.go:1917-1924
**Unconditional behavior change — consider a compat flag**

Route-registration order now follows spec declaration order for all backends and all users, with no opt-out. The project's stated practice is that behavior-changing features be opt-in via a configuration flag (`compatibility` or `output-options`) rather than silent breaking changes. Users on order-dependent routers (Fiber, Gorilla/mux) who previously worked around the alphabetical ordering by arranging their spec paths alphabetically will silently get different runtime routing on the next code-gen run. It is worth asking whether this should be gated behind a flag (e.g. `compatibility.register-routes-in-spec-order`) so the change is opt-in rather than unconditional.

Reviews (1): Last reviewed commit: "Register handlers in spec order" | Re-trigger Greptile

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

greptile-apps[bot]
greptile-apps Bot reviewed Jul 13, 2026
View reviewed changes
Comment thread pkg/codegen/operations.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

@mromaszewicz
mromaszewicz merged commit 6574240 into oapi-codegen:main Jul 13, 2026
16 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@mromaszewicz
mromaszewicz deleted the fix/issue-1887 branch July 13, 2026 18:19
@jamietanna

jamietanna commented Jul 17, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

IMO, I think this may be an option we want a compatibility config option for @mromaszewicz, especially if it changes intent for everyone's specs

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mromaszewicz

mromaszewicz commented Jul 17, 2026

Copy link
Copy Markdown
Member Author

This only affects fiber and gorilla, and only in the case where a parameterized shallow path comes before a deeper path.

For example, if you have:

  • /api/something/:param
  • /api/something/anotherthing/foo

The first is going to shadow the second.

In every other router, path registration is order independent, so it's a no-op change, just a bit of generated code churn.

I think I want this default-on, but I can add an opt out flag (even though spec editing can accomplish the same thing)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mromaszewicz mromaszewicz mentioned this pull request Jul 17, 2026
Add sort-handler-registrations flag to opt out of spec-order registra… #2477
Merged
mromaszewicz added a commit to mromaszewicz/oapi-codegen that referenced this pull request Jul 17, 2026
@mromaszewicz @claude
Add sort-handler-registrations flag to opt out of spec-order registra…
ee37409
…tion

PR oapi-codegen#2465 (issue oapi-codegen#1887) changed generated servers to register route handlers in
spec-declaration order, so that routers which match in registration order
(Fiber, Gorilla/mux) can disambiguate overlapping paths by ordering them in the
spec. This makes that behavior opt-out: the new sort-handler-registrations
compatibility flag restores the historical lexicographic (by path, then method)
registration order for users who relied on it.

The dispatch is a single seam -- operationsInRegistrationOrder picks
sortOperationsLexicographically when the flag is set, otherwise the existing
sortOperationsBySpecOrder -- and all nine GenerateXServer functions route
through it. The lexicographic sort reproduces the historical gather order
(SortedMapKeys over paths then methods), so with the flag unset the default
output is unchanged.

Adds TestSortHandlerRegistrations and documents the flag in
configuration-schema.json.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
mromaszewicz added a commit that referenced this pull request Jul 17, 2026
@mromaszewicz @claude
Add sort-handler-registrations flag to opt out of spec-order registra…
de2d8b2
…tion (#2477)

PR #2465 (issue #1887) changed generated servers to register route handlers in
spec-declaration order, so that routers which match in registration order
(Fiber, Gorilla/mux) can disambiguate overlapping paths by ordering them in the
spec. This makes that behavior opt-out: the new sort-handler-registrations
compatibility flag restores the historical lexicographic (by path, then method)
registration order for users who relied on it.

The dispatch is a single seam -- operationsInRegistrationOrder picks
sortOperationsLexicographically when the flag is set, otherwise the existing
sortOperationsBySpecOrder -- and all nine GenerateXServer functions route
through it. The lexicographic sort reproduces the historical gather order
(SortedMapKeys over paths then methods), so with the flag unset the default
output is unchanged.

Adds TestSortHandlerRegistrations and documents the flag in
configuration-schema.json.

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
@eyoshioka eyoshioka mentioned this pull request Oct 8, 2026
fix: ignore kin-openapi source locations when comparing type definitions #2601
Merged
mromaszewicz added a commit that referenced this pull request Oct 31, 2026
@eyoshioka @claude @mromaszewicz
fix: ignore kin-openapi source locations when comparing type definiti…
b4fdfe1
…ons (#2601)

* fix: ignore kin-openapi source locations when comparing type definitions

Since #2465 the loader sets IncludeOrigin, so every schema records the
line it was declared on. TypeDefinitionsEquivalent compared schemas with
reflect.DeepEqual, so two identical schemas with the same
x-go-type-name on different lines no longer matched, and generation
failed with "duplicate typename".

Compare the schemas like reflect.DeepEqual does, but treat any two
*openapi3.Origin values as equal. Comparing the JSON encodings instead
would drop resolved $ref targets and OpenAPI 3.1 $ref siblings, so
different schemas could be merged silently.

Fixes #2599

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Marcin Romaszewicz <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@greptile-apps greptile-apps[bot] greptile-apps[bot] left review comments

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

bug Something isn't working notable changes Used for release notes to highlight these more highly

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Re-order generated routes

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@mromaszewicz @jamietanna
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.