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

3

6

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.

Larrylars answered 3/9, 2018 at 10:35 Comment(0)
K
2

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.

Kurtzig answered 12/10, 2018 at 13:39 Comment(2)
This does not work. Still shows the ResponseEntity body. You have to actually make the resource method return type "void" to remove the response body from the docs. Unfortunately, I can't find a way to have a ResponseEntity (with headers only for example), which shows as no body in the documentation. :/Compute
Hi, I actually found a solution for returning a ResponseEntity in the resource method, while having it show a void body in the documentation: github.com/springfox/springfox/issues/1884Compute
P
5

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

Praline answered 25/6, 2019 at 20:9 Comment(0)
K
2

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.

Kurtzig answered 12/10, 2018 at 13:39 Comment(2)
This does not work. Still shows the ResponseEntity body. You have to actually make the resource method return type "void" to remove the response body from the docs. Unfortunately, I can't find a way to have a ResponseEntity (with headers only for example), which shows as no body in the documentation. :/Compute
Hi, I actually found a solution for returning a ResponseEntity in the resource method, while having it show a void body in the documentation: github.com/springfox/springfox/issues/1884Compute
M
0

When migrated to Swagger 3 (OpenAPI 3), things changed a little bit.

Instead of response = void.class, you can use content = {@Content(examples = {})}. Probably there are other ways, but this one works good enough.

Mace answered 20/4 at 11:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.