Skip to content

fix: propagate required flag to @RequestHeader-derived headers - #1441

Merged
tangcent merged 1 commit into
masterfrom
fix/1440-requestheader-required-to-yapi
Sep 1, 2026
Merged

tangcent merged 1 commit into
masterfrom
fix/1440-requestheader-required-to-yapi

Conversation

@tangcent

Copy link
Copy Markdown
Owner

Summary

Fixes #1440: header parameters declared with @RequestHeader were exported through a
dedicated extractParamHeaders branch that built ApiHeader without consulting the
param.required rule. As a result headers always carried required = false and YApi
req_headers[].required was always 0, even when the rule resolved to true.

Changes

  • Spring MVC (SpringMvcClassExporter): param.required now wins when configured;
    when no rule is set, the Spring default is applied in code — @RequestHeader is
    required unless required = false is declared explicitly.
  • JAX-RS (JaxRsClassExporter) and custom framework (CustomClassExporter):
    param.required is now honoured for header-bound parameters (previously always
    emitted required = false).
  • Rule engine: added RuleEngine.evaluateOrNull and
    DocMetadataResolver.resolveParamRequired so a framework-specific default can be
    applied only when no rule is configured.
  • YApi (req_headers[].required) and OpenAPI (header.required) consumers now see the
    correct flag.

Tests

  • SpringMvcRequestHeaderRequiredTest — covers the Spring default (no rules), the
    exact custom rule from the report, and rule-overrides-default precedence.
  • JaxRsHeaderRequiredTest — covers rule-driven required propagation for @HeaderParam.
  • YapiFormatterTest — added a contract test for the req_headers[].required mapping.

All new tests pass and the com.itangcent.easyapi.framework.* package is green. The
full suite could not be completed on this machine because the test executor JVM runs
out of native memory (pre-existing environment limitation, unrelated to this change).

Notes

  • Without a param.required rule, @RequestParam (query params) keeps its current
    behaviour (optional). Aligning @RequestParam with the Spring default would be a
    separate, broader change.
  • The header name for a parameter without a param.name rule still falls back to the
    Java parameter name rather than the @RequestHeader value — pre-existing behaviour,
    out of scope here.

@github-actions github-actions Bot added the type: bug Something isn't working label Aug 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📦 Plugin has been packaged for this PR. You can download it from the GitHub Actions workflow run by clicking on the "Artifacts" dropdown:

  • easy-yapi-3.2.3.252.0.zip — IntelliJ IDEA 2025.2+ (officially supported)
  • easy-yapi-3.2.3.221.251.zip — IntelliJ IDEA 2022.1 – 2025.1 (best-effort, not verified on older IDEs)

Each artifact is a ready-to-install plugin zip — pick the one matching your IDEA version and install it via Settings → Plugins → ⚙ → Install Plugin from Disk. No extraction needed.

@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.76923% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.834%. Comparing base (62e3097) to head (a1a127f).

Files with missing lines Patch % Lines
...yapi/framework/springmvc/SpringMvcClassExporter.kt 76.923% 1 Missing and 2 partials ⚠️
...nt/easyapi/framework/custom/CustomClassExporter.kt 80.000% 0 Missing and 1 partial ⚠️
...cent/easyapi/framework/jaxrs/JaxRsClassExporter.kt 80.000% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##            master     #1441       +/-   ##
=============================================
+ Coverage   66.805%   66.834%   +0.028%     
=============================================
  Files          468       468               
  Lines        27146     27169       +23     
  Branches      6520      6522        +2     
=============================================
+ Hits         18135     18158       +23     
  Misses        6544      6544               
  Partials      2467      2467               
Flag Coverage Δ
unittests 66.834% <80.769%> (+0.028%) ⬆️

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

Files with missing lines Coverage Δ
...ent/easyapi/core/psi/helper/DocMetadataResolver.kt 73.737% <100.000%> (+0.268%) ⬆️
...m/itangcent/easyapi/core/rule/engine/RuleEngine.kt 73.214% <100.000%> (+0.487%) ⬆️
...nt/easyapi/framework/custom/CustomClassExporter.kt 79.638% <80.000%> (+0.375%) ⬆️
...cent/easyapi/framework/jaxrs/JaxRsClassExporter.kt 85.075% <80.000%> (+0.459%) ⬆️
...yapi/framework/springmvc/SpringMvcClassExporter.kt 84.898% <76.923%> (-0.081%) ⬇️

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 62e3097...a1a127f. Read the comment docs.

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

Header parameters declared with @RequestHeader are exported through a
dedicated extractParamHeaders branch that built ApiHeader without
consulting the param.required rule, so headers always carried
required=false and YApi req_headers[].required was always 0.

- resolve param.required for header-bound parameters in the Spring MVC,
  JAX-RS and custom exporters
- add RuleEngine.evaluateOrNull and DocMetadataResolver.resolveParamRequired
  so a framework default can be applied when no rule is configured:
  @RequestHeader is required unless required=false is declared
- add regression tests covering the Spring default, the custom-rule
  override and rule precedence, plus a YApi formatter contract test
@tangcent
tangcent force-pushed the fix/1440-requestheader-required-to-yapi branch from d0f72ec to a1a127f Compare August 31, 2026 23:56
@github-actions

Copy link
Copy Markdown
Contributor

📦 Plugin has been packaged for this PR. You can download it from the GitHub Actions workflow run by clicking on the "Artifacts" dropdown:

  • easy-yapi-3.2.3.252.0.zip — IntelliJ IDEA 2025.2+ (officially supported)
  • easy-yapi-3.2.3.221.251.zip — IntelliJ IDEA 2022.1 – 2025.1 (best-effort, not verified on older IDEs)

Each artifact is a ready-to-install plugin zip — pick the one matching your IDEA version and install it via Settings → Plugins → ⚙ → Install Plugin from Disk. No extraction needed.

@bobexchen

Copy link
Copy Markdown

Confirmed working. I installed the artifact build (easy-yapi-3.2.3.252.0.zip) and exported to YApi again — req_headers[].required now correctly reflects the @RequestHeader#required attribute:

  • @RequestHeader("x-user-id")required: 1
  • @RequestHeader(value = "x-timezone-id", required = false)required: 0

Thanks for the quick fix! Looking forward to the next release.

@tangcent
tangcent merged commit 6b8b4ce into master Sep 1, 2026
12 checks passed
@tangcent
tangcent deleted the fix/1440-requestheader-required-to-yapi branch September 1, 2026 23:42
@github-actions github-actions Bot mentioned this pull request Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] @RequestHeader required is not propagated to YApi req_headers (always 0)

2 participants