Skip to content

[java][jaxrs-spec][quarkus] Add @ResponseStatus annotation HTTP success codes#23628

Open
Ignacio-Vidal wants to merge 5 commits intoOpenAPITools:masterfrom
Ignacio-Vidal:java-quarkus-respnose-status
Open

[java][jaxrs-spec][quarkus] Add @ResponseStatus annotation HTTP success codes#23628
Ignacio-Vidal wants to merge 5 commits intoOpenAPITools:masterfrom
Ignacio-Vidal:java-quarkus-respnose-status

Conversation

@Ignacio-Vidal
Copy link
Copy Markdown

@Ignacio-Vidal Ignacio-Vidal commented Apr 26, 2026

When using the jaxrs-spec generator with ibrary=quarkus, interfaceOnly=true, and returning plain POJOs (i.e. returnResponse=false and returnJBossResponse=false), RESTEasy Reactive always defaults the HTTP response status to 200 OK. If the OpenAPI specification declares a different primary success code (e.g. 201 Created on a POST, or a 3xx redirect), the generated interface had no way to communicate that status without wrapping the return type in RestResponse or Response.

This PR adds support for @org.jboss.resteasy.reactive.ResponseStatus on generated interface methods, following the Quarkus REST guide.

Behaviour:

  • For each operation, the first non-200 2xx or 3xx response code declared in the spec is selected as the default status.
  • 200 is also annotated for completeness purposes, even through it is already the RESTEasy Reactive default. This makes it explicit to any code readers and avoids having implicit knowledge of RESTeasy deafult behaviour.
  • The annotation is not emitted when returnResponse=true or returnJBossResponse=true, because those modes use the Response/RestResponse builder to set the status directly.
  • The annotation is only emitted for the quarkus library; other JAX-RS library targets are unaffected.
  • The import import org.jboss.resteasy.reactive.ResponseStatus; is conditionally added to the generated file only when at least one method in the class requires the annotation.

Example: Given a spec with:

post:
  responses:
    '201':
      description: Created

Then it generates an ApiInterface:

@POST
@Consumes({ "application/json" })
@Produces({ "application/json" })
@ResponseStatus(201)  ----> Addition by this pull request
PetResponse createPet(@Valid @NotNull PetRequest petRequest);

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.

Summary by cubic

Adds @org.jboss.resteasy.reactive.ResponseStatus to Quarkus jaxrs-spec generated APIs so plain return types reflect the spec’s 2xx/3xx success code without using Response/RestResponse. Adds the RESTEasy Reactive dependency only when the annotation is generated.

  • New Features

    • Generates @ResponseStatus(<code>) on interface and class methods using the first success code (2xx/3xx), including 200.
    • Quarkus-only; skipped when returnResponse=true or returnJBossResponse=true. Imports ResponseStatus only when needed.
  • Dependencies

    • Adds io.quarkus.resteasy.reactive:resteasy-reactive to the generated pom.xml when response status annotations are emitted (or when returnJBossResponse=true).

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

@Ignacio-Vidal Ignacio-Vidal changed the title [java][jaxrs-spec][quarkus] Add @ResponseStatus annotation for non-default HTTP success codes [java][jaxrs-spec][quarkus] Add @ResponseStatus annotation HTTP success codes Apr 26, 2026
@Ignacio-Vidal Ignacio-Vidal marked this pull request as ready for review April 26, 2026 23:14
@Ignacio-Vidal
Copy link
Copy Markdown
Author

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

No issues found across 16 files

@wing328
Copy link
Copy Markdown
Member

wing328 commented Apr 27, 2026

please follow step 3 to update the samples.

@Ignacio-Vidal
Copy link
Copy Markdown
Author

I will try again and post here once completed. I noticed the third script hangs and never finishes on macos.

@Ignacio-Vidal Ignacio-Vidal force-pushed the java-quarkus-respnose-status branch from 8765ebc to 30ea37b Compare April 27, 2026 17:56
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

5 issues found across 7 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/generators/kotlin-spring.md">

<violation number="1" location="docs/generators/kotlin-spring.md:316">
P2: kotlin-spring docs now incorrectly mark `oneOf` as unsupported, contradicting generator feature declarations and likely misleading users.</violation>
</file>

<file name="samples/client/petstore/csharp/generichost/latest/NullTypes/docs/models/Widget.md">

<violation number="1" location="samples/client/petstore/csharp/generichost/latest/NullTypes/docs/models/Widget.md:11">
P3: `DebugInfo` documentation is inconsistent: the type column says `Null`, but the description still claims it maps to nullable `Object` in C#.</violation>
</file>

<file name="samples/client/petstore/csharp/generichost/latest/NullTypes/src/Org.OpenAPITools/Model/NullTypeDirect.cs">

<violation number="1" location="samples/client/petstore/csharp/generichost/latest/NullTypes/src/Org.OpenAPITools/Model/NullTypeDirect.cs:152">
P1: Converter incorrectly rejects null for an OAS `type: null` property, causing valid read/write payloads with `alwaysNull: null` to fail.</violation>
</file>

<file name="samples/client/petstore/csharp/generichost/latest/NullTypes/docs/models/NullTypeDirect.md">

<violation number="1" location="samples/client/petstore/csharp/generichost/latest/NullTypes/docs/models/NullTypeDirect.md:8">
P2: The updated model docs are internally inconsistent: the property type is `Null` but the description still says it maps to nullable `Object`, which can mislead users.</violation>
</file>

<file name="docs/generators/java.md">

<violation number="1" location="docs/generators/java.md:100">
P2: `useJackson3` docs were changed to exclude `apache-httpclient`, but generator code still supports it, creating a user-facing documentation/behavior mismatch.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread docs/generators/kotlin-spring.md Outdated
Comment thread docs/generators/java.md Outdated
Comment thread samples/client/petstore/csharp/generichost/latest/NullTypes/docs/models/Widget.md Outdated
@Ignacio-Vidal Ignacio-Vidal force-pushed the java-quarkus-respnose-status branch 2 times, most recently from 30ea37b to daf076f Compare April 28, 2026 21:14
@Ignacio-Vidal Ignacio-Vidal marked this pull request as draft April 28, 2026 21:16
@Ignacio-Vidal Ignacio-Vidal marked this pull request as ready for review April 28, 2026 21:16
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

2 issues found across 16 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/apiMethod.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/apiMethod.mustache:47">
P2: `@ResponseStatus` is emitted on Quarkus stub methods that return explicit `Response`, where Quarkus ignores the annotation; this can produce misleading generated status contracts.</violation>

<violation number="2" location="modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/apiMethod.mustache:47">
P1: Raw injection of success response code into `@ResponseStatus(...)` can generate invalid Java for range keys like `2XX`, causing compile failures.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

}){{^-last}},{{/-last}}{{/responses}}
}){{/hasProduces}}{{/useMicroProfileOpenAPIAnnotations}}
public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}Response{{/returnJBossResponse}}{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
{{#vendorExtensions.x-java-success-response-code}}@ResponseStatus({{{vendorExtensions.x-java-success-response-code}}})
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.

P1: Raw injection of success response code into @ResponseStatus(...) can generate invalid Java for range keys like 2XX, causing compile failures.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/apiMethod.mustache, line 47:

<comment>Raw injection of success response code into `@ResponseStatus(...)` can generate invalid Java for range keys like `2XX`, causing compile failures.</comment>

<file context>
@@ -44,6 +44,7 @@
             }){{^-last}},{{/-last}}{{/responses}}
         }){{/hasProduces}}{{/useMicroProfileOpenAPIAnnotations}}
-    public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}Response{{/returnJBossResponse}}{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
+    {{#vendorExtensions.x-java-success-response-code}}@ResponseStatus({{{vendorExtensions.x-java-success-response-code}}})
+    {{/vendorExtensions.x-java-success-response-code}}public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}Response{{/returnJBossResponse}}{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
         return {{#supportAsync}}{{#useMutiny}}Uni.createFrom().item({{/useMutiny}}{{^useMutiny}}CompletableFuture.supplyAsync(() -> {{/useMutiny}}{{/supportAsync}}Response.ok().entity("magic!").build(){{#supportAsync}}){{/supportAsync}};
</file context>

}){{^-last}},{{/-last}}{{/responses}}
}){{/hasProduces}}{{/useMicroProfileOpenAPIAnnotations}}
public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}Response{{/returnJBossResponse}}{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
{{#vendorExtensions.x-java-success-response-code}}@ResponseStatus({{{vendorExtensions.x-java-success-response-code}}})
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.

P2: @ResponseStatus is emitted on Quarkus stub methods that return explicit Response, where Quarkus ignores the annotation; this can produce misleading generated status contracts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/JavaJaxRS/spec/libraries/quarkus/apiMethod.mustache, line 47:

<comment>`@ResponseStatus` is emitted on Quarkus stub methods that return explicit `Response`, where Quarkus ignores the annotation; this can produce misleading generated status contracts.</comment>

<file context>
@@ -44,6 +44,7 @@
             }){{^-last}},{{/-last}}{{/responses}}
         }){{/hasProduces}}{{/useMicroProfileOpenAPIAnnotations}}
-    public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}Response{{/returnJBossResponse}}{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
+    {{#vendorExtensions.x-java-success-response-code}}@ResponseStatus({{{vendorExtensions.x-java-success-response-code}}})
+    {{/vendorExtensions.x-java-success-response-code}}public {{#supportAsync}}{{#useMutiny}}Uni{{/useMutiny}}{{^useMutiny}}CompletionStage{{/useMutiny}}<{{/supportAsync}}{{#returnJBossResponse}}{{>returnResponseTypeInterface}}{{/returnJBossResponse}}{{^returnJBossResponse}}Response{{/returnJBossResponse}}{{#supportAsync}}>{{/supportAsync}} {{nickname}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>cookieParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{^-last}},{{/-last}}{{/allParams}}) {
         return {{#supportAsync}}{{#useMutiny}}Uni.createFrom().item({{/useMutiny}}{{^useMutiny}}CompletableFuture.supplyAsync(() -> {{/useMutiny}}{{/supportAsync}}Response.ok().entity("magic!").build(){{#supportAsync}}){{/supportAsync}};
</file context>

@Ignacio-Vidal Ignacio-Vidal force-pushed the java-quarkus-respnose-status branch from daf076f to 4f7b018 Compare April 28, 2026 21:21
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