Bug Report Checklist
Description
When using the openapi-yaml generator to produce a merged (flattened) OpenAPI specification with all $ref references resolved, the HTTP operations (methods) under each path are reordered alphabetically instead of preserving the original declaration order from the source YAML file.
For example, if a path defines operations in the order GET, POST, PUT, PATCH, DELETE, the merged output reorders them to DELETE, GET, PATCH, POST, PUT. This silently breaks the intended ordering despite the source OpenAPI files being defined correctly.
We maintain internal API documentation conventions that prescribe a specific HTTP method order (e.g., CRUD: GET -> POST -> PUT -> PATCH -> DELETE). The merged spec is used as the source of truth for downstream API consumers and documentation tools (e.g., Swagger). Because the generator reorders operations, consumers see them in an unexpected sequence, leading to confusion and inconsistency between the authored spec and the rendered documentation.
openapi-generator version
Reproduced with v7.14.0. The issue likely affects all versions of the openapi-yaml generator that do not set skipSortingOperations.
OpenAPI declaration file content or url
Input spec (sample-api-v1.yaml):
openapi: 3.0.3
info:
title: Sample API
version: 1.0.0
tags:
- name: orders
description: Order management operations
paths:
/orders:
get:
tags:
- orders
summary: List all orders
operationId: listOrders
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Order'
post:
tags:
- orders
summary: Create a new order
operationId: createOrder
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
responses:
'201':
description: order created
/orders/{orderId}:
get:
tags:
- orders
summary: Get order by ID
operationId: getOrderById
parameters:
- name: orderId
in: path
required: true
schema:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
put:
tags:
- orders
summary: Update an order
operationId: updateOrder
parameters:
- name: orderId
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
responses:
'200':
description: order updated
patch:
tags:
- orders
summary: Partially update an order
operationId: patchOrder
parameters:
- name: orderId
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
responses:
'200':
description: order patched
delete:
tags:
- orders
summary: Delete an order
operationId: deleteOrder
parameters:
- name: orderId
in: path
required: true
schema:
type: string
responses:
'204':
description: order deleted
components:
schemas:
Order:
type: object
required:
- id
properties:
id:
type: string
description:
type: string
status:
type: string
enum:
- pending
- completed
- cancelled
Generation Details
java -jar openapi-generator-cli.jar generate \
-i sample-api-v1.yaml \
-g openapi-yaml \
-o ./output
Or via Gradle plugin:
tasks.register<GenerateTask>("generateMergedSpec") {
generatorName.set("openapi-yaml")
inputSpec.set("$projectDir/api/sample-api-v1.yaml")
outputDir.set("${layout.buildDirectory.get().asFile}/merged-spec")
configOptions.put("outputFile", "sample-api-v1.yaml")
}
Steps to reproduce
- Save the YAML spec above as
sample-api-v1.yaml.
- Generate the merged spec using the
openapi-yaml generator (via CLI or Gradle plugin).
- Open the generated output file (e.g.
build/merged-spec/sample-api-v1.yaml for the Gradle example, or output/openapi/openapi.yaml for the CLI).
- Inspect the HTTP methods under
/orders/{orderId}.
Expected: Operations preserve the source file order:
/orders/{orderId}:
get:
...
put:
...
patch:
...
delete:
...
Actual: Operations are reordered alphabetically by HTTP method:
/orders/{orderId}:
delete:
...
get:
...
patch:
...
put:
...
This causes documentation tools to display operations in an unintuitive order (DELETE before GET), creating confusion for API consumers who see a different ordering than what was intentionally defined in the source spec.
Related issues/PRs
Suggest a fix
The openapi-yaml generator (OpenAPIYamlGenerator) should override getSkipSortingOperations() to return true by default, similar to the fix applied in #22163 for python-fastapi.
The openapi-yaml generator is primarily used to resolve $ref references and produce a flat, self-contained YAML file. Sorting operations is counterproductive in this use case, as the purpose is to faithfully represent the original spec with resolved references, not to rearrange it.
Alternatively, a global skipSortingOperations config option could be exposed so users of any generator can opt out of operation sorting.
Bug Report Checklist
Description
When using the
openapi-yamlgenerator to produce a merged (flattened) OpenAPI specification with all$refreferences resolved, the HTTP operations (methods) under each path are reordered alphabetically instead of preserving the original declaration order from the source YAML file.For example, if a path defines operations in the order
GET, POST, PUT, PATCH, DELETE, the merged output reorders them toDELETE, GET, PATCH, POST, PUT. This silently breaks the intended ordering despite the source OpenAPI files being defined correctly.We maintain internal API documentation conventions that prescribe a specific HTTP method order (e.g., CRUD:
GET -> POST -> PUT -> PATCH -> DELETE). The merged spec is used as the source of truth for downstream API consumers and documentation tools (e.g., Swagger). Because the generator reorders operations, consumers see them in an unexpected sequence, leading to confusion and inconsistency between the authored spec and the rendered documentation.openapi-generator version
Reproduced with v7.14.0. The issue likely affects all versions of the
openapi-yamlgenerator that do not setskipSortingOperations.OpenAPI declaration file content or url
Input spec (
sample-api-v1.yaml):Generation Details
Or via Gradle plugin:
Steps to reproduce
sample-api-v1.yaml.openapi-yamlgenerator (via CLI or Gradle plugin).build/merged-spec/sample-api-v1.yamlfor the Gradle example, oroutput/openapi/openapi.yamlfor the CLI)./orders/{orderId}.Expected: Operations preserve the source file order:
Actual: Operations are reordered alphabetically by HTTP method:
This causes documentation tools to display operations in an unintuitive order (DELETE before GET), creating confusion for API consumers who see a different ordering than what was intentionally defined in the source spec.
Related issues/PRs
python-fastapiby enablingskipSortingOperations, but the same problem exists in theopenapi-yamlgenerator.Suggest a fix
The
openapi-yamlgenerator (OpenAPIYamlGenerator) should overridegetSkipSortingOperations()to returntrueby default, similar to the fix applied in #22163 forpython-fastapi.The
openapi-yamlgenerator is primarily used to resolve$refreferences and produce a flat, self-contained YAML file. Sorting operations is counterproductive in this use case, as the purpose is to faithfully represent the original spec with resolved references, not to rearrange it.Alternatively, a global
skipSortingOperationsconfig option could be exposed so users of any generator can opt out of operation sorting.