[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.