Skip to content

Support relative URLs in OpenAPI servers[].url β€” Java (#159)#160

Merged
josephbirkner merged 4 commits into
release/2.0.0from
relative-server-urls
Jun 19, 2026
Merged

Support relative URLs in OpenAPI servers[].url β€” Java (#159)#160
josephbirkner merged 4 commits into
release/2.0.0from
relative-server-urls

Conversation

@fklebert

@fklebert fklebert commented May 18, 2026

Copy link
Copy Markdown
Contributor

Changes

Java-side implementation of #159 β€” support relative URLs in OpenAPI servers[].url.

Note: This PR originally also carried the C++/Python implementation. That portion has been split out as #162 (targeting main) so the fix for #159 can ship in a release independently of the Java client work (#158). This PR now contains only the Java implementation and continues to target jzswag.

OpenAPI 3.0+ (clarified in OpenAPI 3.2.0 Β§4.5.2.1) permits three URL forms in servers[].url:

Form Example Resolves to
Absolute https://api.example.com/v1 itself
Server-relative /v1 spec's scheme://host + /v1
Document-relative ., ./v2, ../v2, v2 resolved against the spec URL's directory via RFC 3986 Β§5.3

Implementation

Java β€” java.net.URI.resolve does the work

  • OpenApiClient.resolveBaseUrl is rewritten to use specUri.resolve(serverRef). The JDK already implements RFC 3986 Β§5.3.
  • Split into an instance wrapper (picks servers[serverIndex].url, defaulting to "/" for an absent/empty servers array per Β§4.7.5) and a package-private static resolver so tests can exercise each branch directly.
  • Integrated with the serverIndex multi-server selection from Support Multiple servers Β #113 β€” the rebase onto current jzswag resolves the overlap in resolveBaseUrl and merges both features' README sections.
  • Works for both HTTP and file:// spec locations.

Tests

  • New OpenApiClientBaseUrlTest (13 tests) covering all three URL forms plus edge cases.
  • Full Java suite passing after rebase: 260 tests across the four modules (api 59, shared 124, jvm 46, android 31), 0 failures.

Merge order

#162 β†’ main (release for #159) β†’ merge main into jzswag β†’ this PR. The README feature matrix added here claims document-relative support for C++/Python, which holds once jzswag contains the #162 changes.

@github-actions

github-actions Bot commented May 18, 2026

Copy link
Copy Markdown

Java Coverage (api / shared / jvm / android)

Overall Project 72.54% -0.08% 🍏
Files changed 91.35% 🍏

Module Coverage
jzswag-shared 75.98% -0.16% 🍏
Files
Module File Coverage
jzswag-shared OpenApiClient.java 61.4% -0.84% 🍏

@codecov

codecov Bot commented May 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.26087% with 5 lines in your changes missing coverage. Please review.
βœ… Project coverage is 66.66%. Comparing base (8c61997) to head (5190a4b).
⚠️ Report is 5 commits behind head on release/2.0.0.

Files with missing lines Patch % Lines
...va/io/github/ndsev/zswag/shared/OpenApiClient.java 78.26% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@                 Coverage Diff                 @@
##             release/2.0.0     #160      +/-   ##
===================================================
+ Coverage            66.17%   66.66%   +0.49%     
- Complexity             477      480       +3     
===================================================
  Files                   29       29              
  Lines                 2093     2097       +4     
  Branches               417      415       -2     
===================================================
+ Hits                  1385     1398      +13     
+ Misses                 515      507       -8     
+ Partials               193      192       -1     
Flag Coverage Ξ”
unittests-java 66.66% <78.26%> (+0.49%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

β˜” View full report in Codecov by Harness.
πŸ“’ Have feedback on the report? Share it here.

πŸš€ New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

fklebert added a commit that referenced this pull request May 18, 2026
codecov/patch on PR #160 flagged 36.36% patch coverage on
OpenApiClient.java because the previous test class verified
java.net.URI.resolve() in isolation β€” the production method's
branches (file:// fallback, URISyntaxException paths, etc.) weren't
hit by any test.

Refactor:
* Extract resolveBaseUrl(specLocation, serverUrl) as a static
  package-private helper. The instance method delegates to it.
* OpenApiClientBaseUrlTest now calls the static helper directly,
  exercising every branch including the file:// + relative warning,
  the malformed-URI path, and the file URI + document-relative case.
* Keep one end-to-end test that constructs a real OpenApiClient from
  a temp-file spec so the wiring stays verified.

Tests in this class: 9 -> 13. All 236 Java tests still passing.
fklebert added 3 commits June 12, 2026 12:16
The OpenAPI Options Interoperability section showed servers as a
single βœ”οΈ row with an example using only the historically-supported
form (absolute URL with path prefix). Expand to show all three forms
from OpenAPI 3.0+ (clarified in 3.2.0 Β§4.5.2.1) with concrete examples,
and split the matrix row to make clear which forms are supported per
client.

The 'document-relative' row is marked n/a for OAServer and zswag.gen
since neither consumes servers[].url at runtime β€” OAServer routes
based on operation paths, zswag.gen emits whatever the user supplies.
Rewrites OpenApiClient.resolveBaseUrl to use java.net.URI.resolve,
which natively implements RFC 3986 Β§5.3 reference resolution.

Previous implementation handled only:
  - Empty server URL  (used spec origin)
  - URL starting with '/' (path-only, combined with spec origin)
  - Absolute URL (returned as-is)

It silently broke for document-relative forms ('.', './v2', '../v2',
bare 'v2') β€” the else-branch returned them unchanged, producing
nonsense like "." concatenated with the operation path at request time.

The new implementation:
  * Converts spec location to java.net.URI (http(s)://, file://, or local
    path -> file URI)
  * Converts server URL to java.net.URI as a reference
  * Returns specBase.resolve(serverRef)

Works for all three URL forms against both HTTP and local-file spec
locations. The earlier "absolute server URL with local-file spec"
behaviour is preserved via an explicit check (avoids producing a
file:// base URL when the server URL is absolute).

OpenApiClientBaseUrlTest covers each reference form via direct URI
resolution (decoupling the test from the spec-fetch path) plus two
end-to-end tests against a real OpenApiClient using a temp-file spec.

Closes #159 (Java side; C++/Python handled in the preceding commit).
codecov/patch on PR #160 flagged 36.36% patch coverage on
OpenApiClient.java because the previous test class verified
java.net.URI.resolve() in isolation β€” the production method's
branches (file:// fallback, URISyntaxException paths, etc.) weren't
hit by any test.

Refactor:
* Extract resolveBaseUrl(specLocation, serverUrl) as a static
  package-private helper. The instance method delegates to it.
* OpenApiClientBaseUrlTest now calls the static helper directly,
  exercising every branch including the file:// + relative warning,
  the malformed-URI path, and the file URI + document-relative case.
* Keep one end-to-end test that constructs a real OpenApiClient from
  a temp-file spec so the wiring stays verified.

Tests in this class: 9 -> 13. All 236 Java tests still passing.
@fklebert fklebert force-pushed the relative-server-urls branch from 44d7a53 to 1688891 Compare June 12, 2026 10:19
@fklebert fklebert changed the title Support relative URLs in OpenAPI servers[].url (#159) Support relative URLs in OpenAPI servers[].url β€” Java (#159) Jun 12, 2026

@josephbirkner josephbirkner left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ‘πŸ‘

Base automatically changed from jzswag to release/2.0.0 June 19, 2026 14:46
@josephbirkner josephbirkner merged commit 263587f into release/2.0.0 Jun 19, 2026
15 of 24 checks passed
@josephbirkner josephbirkner deleted the relative-server-urls branch June 19, 2026 14:55
@github-actions

Copy link
Copy Markdown
Package Line Rate Branch Rate Health
libs.httpcl.include.httpcl 81% 50% βœ”
libs.httpcl.src 85% 53% βœ”
libs.zswagcl.include.zswagcl.private 29% 14% ❌
libs.zswagcl.src 80% 46% βœ”
Summary 78% (1686 / 2149) 49% (2036 / 4191) βž–

Minimum allowed line rate is 65%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants