Bugfix to solve mixed correct and error response in produces annotation (#24948)

Merged
AN
2mo ago
+315-13

Fixes #24948. Follow-up to #23935.

With splitOperationsByContentType=true, a variant generated for a non-JSON media-type (getReportAsCsv, typed on text/csv) still sent Accept: application/json whenever the operation also declared a JSON error response: produces is the union of every response's content, and every generator picks the Accept from that list with a rule that prefers JSON. Server generators had the mirror problem: two variants of the same route both declared application/json in produces, an ambiguous mapping.

A variant's produces is now the single media-type it was narrowed to, nothing else:

  • Core : fromOperation builds it from the method response alone, getProducesInfo returns the same media-type. Error responses keep their own content and typing.
  • Java : AbstractJavaCodegen stamps x-accepts / x-content-type on the variants as they are split (they were computed in preprocessOpenAPI, before the split). Computing them in fromOperation was tried and dropped: 48 samples changed, the extensions being exported into the serialized openapi.yaml.
  • rust-server-deprecated : usesXml set per XML response, as the maintained rust-server does.
  • Docs : global-properties.md updated.

Design note for reviewers: a Spring server variant declares only its own media-type in produces; that is what lets Spring route on Accept without an ambiguous mapping, and JSON error bodies still go through @ExceptionHandler, negotiated on the client's Accept. Opinions welcome.

  • Unsplit operations generate byte-identical output. Everything is behind the opt-in option.
  • Tests : New fixture with JSON error responses

PR checklist

  • [ X ] Read the contribution guidelines.
  • [ X ] 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.
  • [ X ] If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@wing328

@cachescrubber (2022/02) @welshm (2022/02) @MelleD (2022/02) @atextor (2022/02) @manedev79 (2022/02) @javisst (2022/02) @borsch (2022/02) @banlevente (2022/02) @Zomzog (2022/09) @martin-mfg (2023/08) @KannaKim (2026/07)


Summary by cubic

Fixes #24948, a follow-up to #23935. With splitOperationsByContentType=true, a variant narrowed on the response axis still sent Accept: application/json when the operation also declared a JSON error response, because produces was the union of all response media types. Such variants now produce only the media type they were narrowed to; error responses keep their own content and typing. Variants split only on the request axis keep the operation's original produces, error responses included.

  • Java generators restamp x-accepts and x-content-type after the split, so each variant carries its own media types instead of inheriting the original operation's.
  • rust-server-deprecated sets usesXml per XML response, and the behavior is documented in docs/global-properties.md.
  • Unsplit operations generate byte-identical output, since the fix is limited to the opt-in split path.