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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With