When using Springfox, you can annotate endpoints to automatically generate OpenAPI documentation for clients.
here we will learn how to prevent Springfox from generating models on endpoints with ResponseEntity as the return type.
I will additionally justify the way to stop the default response from being generated.
An Example
Here we want to return ResponseEntity because we want control over the status and body which is returned within your endpoint code
@PostMapping @ApiOperation(value = "Object created") @ApiResponses({ @ApiResponse(code = 202, message = "Object accepted sucessfully."), @ApiResponse(code = 400) }) public ResponseEntity createObject( @RequestBody @Valid CreateObjectRequest request) { try { // handle object creation return accepted().build(); } catch (Throwable throwable) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(ErrorResponse.builder() .errorCode("request.failed") .message(exception.getMessage()) .build() ); } }
Spingfox configuration used for this example
@Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .securitySchemes(List.of(apiKey)) .securityContexts(List.of(securityContext)) .apiInfo(metaData()) .host(swaggerHost) .forCodeGeneration(true) .select() .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) .build(); }
Now responses of your Generated OpenAPI doc contains with a $ref to ResponseEntity.
{ "responses": { "202": { "description": "Object accepted sucessfully.", "schema": { "originalRef": "ResponseEntity", "$ref": "#/definitions/ResponseEntity" } } } }
We can also generate some default springfox responses for 201, 202, 400, 401, 403, 404, which we may never required.
Solution
In the example above you’ve seen ResponseEntity is being generated as OpenAPI model, whereas you simply needed to return a 200 without body.
Springfox contains a configuration solution for this that is directModelSubstitute(ResponseEntity.class, Void.class).
We’ve also seen Springfox generates default responses, which you may never requied.
This can resolved by the configuration of useDefaultResponseMessages(false).
The updated configuration is -:
@Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .securitySchemes(List.of(apiKey)) .securityContexts(List.of(securityContext)) .apiInfo(metaData()) .host(swaggerHost) .forCodeGeneration(true) .select() .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) .build(); }
Now the Responses generates are:
{ "200": { "description": "OK" }, "202": { "description": "Object accepted sucessfully." }, "400": { "description": "not a valid request", "schema": { "originalRef": "ErrorResponse", "$ref": "#/definitions/ErrorResponse" } } }
As we can see, it has generated a 200 response for us, but in the @ApiResponseswe have only defined 202 and 400.
This not as expected, but we can be resolved by adding a @ResponseStatus(ACCEPTED) to your endpoint and the 200 response will be omitted.
After all the configuration will complete your updated endpoint will look like this
@ResponseStatus(HttpStatus.ACCEPTED) @PostMapping @ApiOperation(value = "Create a Object") @ApiResponses({ @ApiResponse(code = 202, message = "Object accepted sucessfully."), @ApiResponse(code = 400, message = "invalid") }) public ResponseEntity createObject( @RequestBody @Valid CreateObjectRequest request) { try { // handle object creation return accepted().build(); } catch (Throwable throwable) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(ErrorResponse.builder() .errorCode("request.failed") .message(exception.getMessage()) .build() ); } }
And the generated OpenAPI responses like this
{ "202": { "description": "Object accepted sucessfully." }, "400": { "description": "not a valid request", "schema": { "originalRef": "ErrorResponse", "$ref": "#/definitions/ErrorResponse" } } }
Thank You