Avoid ResponseEntity being generated as OpenAPI model

Posted By :Deepak Singh Chauhan |30th March 2020

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


About Author

Deepak Singh Chauhan

Deepak is a bright Java Developer, having good skills in Java, Servlet and Spring MVC Framework. His hobbies are travel and explore new places and learning about new technologies .

Request For Proposal

[contact-form-7 404 "Not Found"]

Ready to innovate ? Let's get in touch

Chat With Us