Skip to content

[kotlin-spring] add @ModelAttribute to complex non-json query params#23876

Closed
Picazsoo wants to merge 9 commits into
OpenAPITools:masterfrom
Picazsoo:feature/kotlin-spring-add-ModelAttribute-to-query-params2
Closed

[kotlin-spring] add @ModelAttribute to complex non-json query params#23876
Picazsoo wants to merge 9 commits into
OpenAPITools:masterfrom
Picazsoo:feature/kotlin-spring-add-ModelAttribute-to-query-params2

Conversation

@Picazsoo

@Picazsoo Picazsoo commented May 26, 2026

Copy link
Copy Markdown
Contributor

This PR fixes kotlin-spring generator to correctly annotate complex query parameters (isModel=true) with @ModelAttribute("paramName"). Previously, model query params received no Spring binding annotation at all, which meant Spring couldn't reliably bind nested fields like filter.statuses=active in Kotlin where parameter names aren't discoverable without -java-parameters compile flag. Additionally, query params with hyphenated names (e.g. order-status, item-status) that can't be Kotlin identifiers had no way to be bound at all without the explicit annotation value.

A guard was added for the content: application/json case so when the parameter carries a JSON-encoded object as a single string on the parameter (e.g. ?filter={"statuses":["active"]}), @ModelAttribute would be wrong - Spring's data binder would try to read filter.statuses=… style fields rather than deserializing the JSON blob. These params instead properly get @RequestParam annotation, which delivers the raw string to a (user provided and registered) Converter<String, T>.

Tests:

  • The runtime behaviour is verified in the kotlin-springboot-sort-validation sample: OrdersApiImpl uses check() assertions with distinct sentinel values per parameter, so any mis-routing (e.g. order-status.statuses landing in filter) or missing binding (e.g. a hyphenated name not bound at all) returns immediately as HTTP 500.
  • Unit-level coverage lives in KotlinSpringServerCodegenTest with three targeted tests covering deepObject model params, non-Kotlin-identifier param names, and the content: application/json exclusion.

Note: I will eventually implement the same in java-spring as well.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request. - tagging @karismann (2019/03) @Zomzog (2019/04) @andrewemery (2019/10) @4brunu (2019/11) @yutaka0m (2020/03) @stefankoppier (2022/06) @e5l (2024/10) @dennisameling (2026/02)

Summary by cubic

Adds @ModelAttribute("") for complex (model) query parameters in kotlin-spring to enable deepObject binding and preserve wire names, while keeping @RequestParam for JSON-encoded (content: application/json) query params. Updates samples and tests to verify correct binding, including hyphenated names, multiple model params, and valid-identifier params.

  • New Features
    • Generate conditional annotations for model query params: use @ModelAttribute("<baseName>") for deepObject/form-style; use @RequestParam when the param uses content: application/json.
    • Update Kotlin and Java Spring Boot samples: add Orders endpoints and OrderStatus schema, a Kotlin OrdersApi implementation with runtime assertions, a Java controller, and tests (MockMvc + codegen) covering hyphenated names, multiple model params, valid-identifier params, and the JSON-content exclusion.

Written for commit 2634014. Summary will update on new commits. Review in cubic

@Picazsoo Picazsoo marked this pull request as ready for review May 26, 2026 12:20
@Picazsoo Picazsoo marked this pull request as draft May 26, 2026 12:21

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 3 files

Re-trigger cubic

@Picazsoo Picazsoo marked this pull request as ready for review May 26, 2026 13:16

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 8 files

Re-trigger cubic

@Picazsoo Picazsoo changed the title Feature/kotlin spring add model attribute to query params2 [kotlin-spring] add @ModelAttribute to complex query params May 26, 2026
@Picazsoo Picazsoo changed the title [kotlin-spring] add @ModelAttribute to complex query params [kotlin-spring] add @ModelAttribute to complex non-json query params May 26, 2026
@Picazsoo Picazsoo marked this pull request as draft May 26, 2026 20:18
@Picazsoo Picazsoo closed this May 26, 2026
@Picazsoo

Copy link
Copy Markdown
Contributor Author

This implementation is mostly nonsense and was based on incorrect understanding of the matters. Closing the PR.

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.

1 participant