Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove the response body of an operation in Springfox Swagger?

I'm working in a REST service made with spring-boot, which to this day is documented using springfox-swagger2:2.7.0 (implementation first). The last operation I've added looks like this:

@ApiOperation(value = "whatever")
  @ApiResponses({
    @ApiResponse(code = HttpURLConnection.HTTP_NO_CONTENT, message = "Returns empty content when succeeds"),
    @ApiResponse(code = HttpURLConnection.HTTP_FORBIDDEN, message = "You can't do that.")
  })
@CrossOrigin
@PreAuthorize("hasAuthority('USER_ACCESS')")
@RequestMapping(value = "/foo", method = POST, consumes = APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public ResponseEntity postFoo(
  @RequestBody
  FooRequestBody requestBody) {

  if (someMethodReturnsTrue()) {
    return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
  } else {
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
  }
}

Now, the problem is that no matter what, the generated Swagger definition ends up looking like this:

"responses": {
  "204": {
    "description": "Returns empty content when succeeds",
    "schema": {
      "$ref": "#/definitions/ResponseEntity"
    }
  },
  "403": {
    "description": "You can't do that."
  }
}

Provided that this operation returns nothing, I understand that the "204" response should have no schema field (like the other one).

I've tried specifying response = Void.class in the @ApiParam annotation (as suggested in other threads) with no joy (since it is the default value it is indistinguishable from not specifying it).

I've also tried setting genericModelSubstitutes(ResponseEntity.class) in my Docket bean and that did nothing.

I know that instead of returning ResponseEntity I could return void and throw and exception in case someMethodReturnsTrue() returns indeed false. An @ExceptionHandler method could then turn that exception into a 403 status code.

I think this is overkill, I think I shouldn't be changing my implementation to fix my documentation. That's why I ask, is there any way to tell Springfox to ignore the return value of that specific method and treat it as if it returned void?

Thanks.

like image 781
Iñaki Avatar asked Sep 03 '18 10:09

Iñaki


2 Answers

Found the workaround, As the default behavior of @ApiOperation is to return the return type of method, so for every status, the return type of method will be returned. If you want to send empty response then write

@ApiResponse(code = 204, message = "No User found for that Id",response = Object.class)

And in the SwaggerConfig write

 @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .useDefaultResponseMessages(false)
                .directModelSubstitute(Object.class, java.lang.Void.class);          
    }

So whenever an Object.class is returned swagger will automatically convert it into Void.class

like image 175
Vipin Gupta Avatar answered Sep 21 '22 02:09

Vipin Gupta


Add:

@ApiResponse(code = 204, response = void.class, message = "No Content")

to your @ApiResponses({ ... }) annotation. Important is that void.class is used instead of Void.class. So it is different from the default value and you still can use ResponseEntity as a return type.

like image 30
Vladas Maier Avatar answered Sep 20 '22 02:09

Vladas Maier