Skip to content

External schema-file $ref without a #/components/... fragment is not resolved into a model #373

Description

@joseegman-idoneea

External schema-file $ref without a #/components/... fragment is not resolved into a model

Summary

When a schema is referenced as a whole external file — i.e. the file is the schema and
the $ref carries no JSON-pointer fragment — the generator does not turn it into a model.
The operation is generated referencing a DTO that is never emitted, so the generated code
does not compile.

This is the modular-contract style produced by tools like redocly split:

# response content
schema:
  $ref: "./components/schemas/Dashboard.yml"   # whole file is the schema, no #/... fragment
# components/schemas/Dashboard.yml  (the file IS the schema object)
type: object
properties:
  id: { type: string }

Related

Split off from #372 (external Path Item $ref, now fixed). While validating that fix,
a modular contract that also split its schemas into standalone files surfaced this
independent gap. The path-item fix makes the API interface generate; this gap keeps the
corresponding model from generating.

How to reproduce

Reference a schema by whole external file (no fragment) from a response/request/component,
then generate. The API interface is produced and imports e.g.
InlineResponse200GetDashboardDTO / DashboardDTO, but no such model class is written.

Expected

The external file is loaded and generated as a model, named after the referenced file /
component, identical to referencing an inlined equivalent.

Actual

Operation generated referencing a non-existent DTO; no model file emitted; no warning.
Generated sources fail to compile.

Notes / current workaround

The supported external form is a fragment ref into a components-style file, e.g.
$ref: "components.yml#/components/schemas/Dashboard" (see the existing
testExternalRefsGeneration fixture). Contracts using whole-file schema refs must currently
either be bundled/inlined or rewritten to the fragment form.

Root cause pointers

  • ApiTool.getComponentSchemas (common/tools/ApiTool.java:157-171) stores
    components.schemas.X nodes raw; an external-file $ref entry is not dereferenced.
  • Response/request schema handling (openapi/utils/OpenApiUtil.processResponses /
    MapperPathUtil schema-type resolution) only registers inline object schemas or
    fragment component refs as models; a whole-file external $ref matches neither and is
    named as an inline response but never emitted.

Proposed fix

Mirror the Path Item resolution added in #372: dereference whole-file schema $refs (external,
no fragment) at parse time — for components.schemas entries and for request/response content
schemas — substituting the loaded schema node so the existing model pipeline emits it. Add a
regression fixture with schemas split into standalone files.

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