Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Issues
  • #7099
Closed
Open
Issue created Jul 31, 2020 by Administrator@rootContributor

[REQ][jaxrs-spec] Generate typesafe responses from contract

Created by: ruedigerk

Is your feature request related to a problem? Please describe.

I want my Java compiler to be able to typecheck that I can only return responses that are valid according to the contract. This is a feature of the RAML code generator I was using before, but is not available with OpenAPI/OpenAPI-Generator.

Assume I have an operation defined with the following responses in OpenAPI 3:

      responses:
        '200':
          description: successful operation
          content:
            application/xml:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
        '202':
          description: accepted for later processing
          content:
            application/json:
              schema:
                type: string
        '204':
          description: successful operation, but nothing found
        '400':
          description: Invalid parameters

When I generate my Java server code (using "interfaceOnly") with "jaxrs-spec", I have the option to generate with return types, resulting in this Java method for the operation above:

    @GET
    @Path("/findByTags")
    @Produces({ "application/xml", "application/json" })
    List<Pet> findPetsByTags(@QueryParam("tags") @NotNull    List<String> tags);

This is type safe, because of the List<Pet> return type, but it does not allow me to select the status code or content type I want to return in accordance with my contract.

The other option is to use the "returnResponse" option, resulting in this code:

    @GET
    @Path("/findByTags")
    @Produces({ "application/xml", "application/json" })
    Response findPetsByTags(@QueryParam("tags") @NotNull    List<String> tags);

This gives me the flexibility to choose whatever status codes, content types or data to return. But it is also of no help at all to ensure that I actually return responses that are in accordance with my contract. This is a nightmare to keep correct when evolving the application, changing the contract or even just implementing the method for the first time.

Describe the solution you'd like

The RAML code generator I used before solved this problem by generating typesafe response classes derived from the contract. It generated one helper method for each combination of status code and content type in the contract, so that the application is both type safe and able to select the desired response properties. The generated code, including a response class with the required helper methods, would look something like this:

    @GET
    @Path("/findByTags")
    @Produces({ "application/xml", "application/json" })
    FindPetsByTagsResponse findPetsByTags(@QueryParam("tags") @NotNull    List<String> tags);
    
    public static class FindPetsByTagsResponse extends org.openapitools.api.support.ResponseWrapper {
        private FindPetsByTagsResponse(Response delegate) {
            super(delegate);
        }
        public static FindPetsByTagsResponse with200ApplicationXml(List<Pet> entity) {
            return new FindPetsByTagsResponse(Response.status(200).header("Content-Type", "application/xml").entity(entity).build());
        }
        public static FindPetsByTagsResponse with200ApplicationJson(List<Pet> entity) {
            return new FindPetsByTagsResponse(Response.status(200).header("Content-Type", "application/json").entity(entity).build());
        }
        public static FindPetsByTagsResponse with202ApplicationJson(String entity) {
            return new FindPetsByTagsResponse(Response.status(202).header("Content-Type", "application/json").entity(entity).build());
        }
        public static FindPetsByTagsResponse with204() {
            return new FindPetsByTagsResponse(Response.status(204).build());
        }
        public static FindPetsByTagsResponse with400() {
            return new FindPetsByTagsResponse(Response.status(400).build());
        }
        public static FindPetsByTagsResponse withCustomResponse(Response response) {
            return new FindPetsByTagsResponse(response);
        }
    }

I already implemented the suggested scheme in a fork, but I would like to contribute this functionality as I think it adds a lot of value to the generated code. Also, this feature missing is a blocker for adopting OpenAPI-Generator in the company I work.

The withCustomResponse method is for the rare cases that one has to define further properties on the response that would otherwise not be possible.

Assignee
Assign to
Time tracking