Skip to content

Fix #375: resolve nested external $ref and handle content-less responses - #380

Merged
jemacineiras merged 9 commits into
sngular:mainfrom
joseegman-idoneea:feat/375-openapi-3.1-support
Jul 23, 2026
Merged

Fix #375: resolve nested external $ref and handle content-less responses#380
jemacineiras merged 9 commits into
sngular:mainfrom
joseegman-idoneea:feat/375-openapi-3.1-support

Conversation

@joseegman-idoneea

Copy link
Copy Markdown
Contributor

Fixes two blocking bugs in the OpenAPI codegen:

Bug 1 — Nested external $ref resolution (FileNotFoundException)

  • SchemaUtil.solveRef always resolved nested $ref files relative to the main spec directory, causing FileNotFoundException when an external schema file (e.g. schemas/Service.yml) referenced another external file via ./ServiceType.yml.
  • resolveNestedFileRefs now recursively inlines nested file $ref content into the parent schema, resolving relative to the containing file's directory.
  • computeFileSchemaKey normalizes file-based ref values to clean schema-map keys.

Bug 2 — Content-less response handling (NoSuchElementException)

  • MapperPathUtil.buildResponse called Optional.orElseThrow() on missing #-ref responses (204/401/403) and on external-file response $ref entries that were never loaded into responseMap.
  • Now returns early for missing #-ref responses and catches load errors for external-file response $refs.
  • External-file schemas referenced from responses are registered in the schemaMap under the inline POJO name so that processModels can generate the corresponding model.

Tests added

  • testNestedExternalRefs: verifies that $ref: ./ServiceType.yml inside an external schema file is resolved correctly, generating the API interface and both model DTOs.
  • testNoContentResponses: verifies that content-less 204/401/404 $ref responses do not crash the generator.

joseegarcia and others added 6 commits July 22, 2026 15:44
…able)

OpenAPI 3.1 / JSON Schema 2020-12 allows a schema's `type` to be an array,
e.g. type: ["string", "null"] (the nullable idiom that replaces 3.0's
`nullable: true`, and general unions). ApiTool.getType() read the type via
JsonNode.textValue(), which returns null for an array node and collapsed to
"", so every isObject/isArray/isString/isNumber/isDateTime predicate and
MapperUtil.getSimpleType failed -> the generator silently produced wrong or
empty types for those fields.

- ApiTool.getType: when `type` is an array, resolve to the first non-"null"
  entry ("null" only marks the type as nullable). All the isX predicates and
  getSimpleType then work unchanged for union/nullable types.
- MapperUtil.processNumber: read the type via ApiTool.getType instead of
  schema.get("type").asText(), so array-valued numeric types resolve.
- Add TypeConstants.NULL.
- Add a 3.1.0 regression fixture (testOpenApi31Types) covering ["string",
  "null"], ["integer","null"], ["number","null"]+double, int64 and a plain
  array, with golden assets.

Bumps version 6.3.2 -> 6.4.0 across the engine, maven and gradle modules.
Non-array `type` handling is unchanged, so existing 3.0 specs are unaffected.

Follow-up 3.1 items (examples array, $ref siblings, webhooks) tracked in sngular#375.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Gradle 9.x plugin validation fails the build when a task type is neither
@CacheableTask nor @DisableCachingByDefault. OpenApiTask and AsyncApiTask
are code generators whose spec-file inputs are not declared as cacheable
inputs, so caching is disabled explicitly with a documented reason.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codacy-production

codacy-production Bot commented Jul 23, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 31 complexity · 0 duplication

Metric Results
Complexity 31
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

joseegarcia and others added 3 commits July 23, 2026 12:45
…support

# Conflicts:
#	multiapi-engine/pom.xml
#	multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java
#	multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java
#	multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java
#	scs-multiapi-gradle-plugin/build.gradle
#	scs-multiapi-maven-plugin/pom.xml
The annotation reason pushed the line to 121 chars, tripping Codacy's
120-char limit (2 new issues). Trim the wording; behaviour is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codacy flagged the Gradle task glue classes for "missing Javadoc" (the
project does not use Javadoc) and generated test-resource fixtures for
style rules that do not apply to generated code. Exclude both so the
analysis only reports real, actionable issues.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jemacineiras jemacineiras self-assigned this Jul 23, 2026
@jemacineiras jemacineiras added bug Something isn't working release Adding this tag to a PR will cause a release on merge labels Jul 23, 2026
@jemacineiras
jemacineiras merged commit 1e36d51 into sngular:main Jul 23, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working release Adding this tag to a PR will cause a release on merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants