Skip to content

v3.1: Unwanted/Unexpected naming behaviour when migrating to 3.0.3 to 3.1.0 #5181

@Ayushp7845

Description

@Ayushp7845

Description

After upgrading an API specification from OpenAPI 3.0.3 to 3.1.0, I observed a change in how schemas are identified and named.

When a response schema is defined externally and referenced via $ref, operation-based response model names name are generated instead of using the original schema, even when the referenced schema is explicitly named.

This results in verbose and unstable class/model names that depend on the endpoint and HTTP status code rather than the schema definition itself.

Observed Behavior

Example:
For example I have a 'schemas' directory and inside there are .yaml files containing schemas which can be used inside my main swagger.yaml file.

api/
├── swagger.yaml
└── schemas/
    └── common.yaml

swagger.yaml

openapi: 3.1.0

info:
  title: Example API
  version: 1.0.0

paths:
  /items:
    get:
      summary: Retrieve a list of items
      operationId: getItems
      responses:
        200:
          description: Successful response
          content:
            application/json:
              schema:
                $ref: schemas/common.yaml#/components/schemas/ListResponse

schemas/common.yaml

components:
  schemas:
    ListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Item'
        total:
          type: integer
      required:
        - data
        - total

    Item:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - id
        - name

Observed Result

When generating models from swagger.yaml, tools generate response models named similarly to:

GetItems200Response
GetItems200ResponseDataInner

Instead of using the referenced schema name:

ListResponse
Item

Expected behavior

Because ListResponse and Item are explicitly named schemas, generator should be able to reuse those names when generating models, regardless of the schemas being defined in an external file.

What I have tried

1. Defined schemas in the root components/schemas

swagger.yaml

openapi: 3.1.0

info:
  title: Example API
  version: 1.0.0

paths:
  /items:
    get:
      summary: Retrieve items
      operationId: getItems
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListResponse'

components:
  schemas:
    ListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Item'
        total:
          type: integer
      required:
        - data
        - total

    Item:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - id
        - name

Observed result

Tooling generates clean, reusable models:

ListResponse
Item

(or prefixed equivalents, depending on generator configuration)

2. Defined schemas in the root components/schemas but with $ref

swagger.yaml

openapi: 3.1.0

info:
  title: Example API
  version: 1.0.0

paths:
  /items:
    get:
      summary: Retrieve items
      operationId: getItems
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListResponse'

components:
  schemas:
    ListResponse:
      $ref: 'schemas/common.yaml#/ListResponse'

Observed result

Generates clean, reusable model for the ListResponse,
but the data field inside the ListResponse.java is List<GetItems200ResponseDataInner> data;

This demonstrates that schema identity is only preserved at the first level. Nested schemas referenced inside externally defined schemas still lose their original names and are treated as anonymous, resulting in operation-based generated names.

Questions / Expected Guidance

  1. Is this behavior an intentional design decision in OpenAPI 3.1?
  2. Should tools be expected to preserve the names of referenced schemas,
    regardless of whether they are defined in the root document or an external file?
  3. Is there any planned mechanism (or recommended pattern) for preserving schema
    identity across files without redefining all schemas under the root
    components/schemas?
  4. If this is expected behavior, should it be explicitly documented in the
    specification to avoid confusion when upgrading from OpenAPI 3.0.x?

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