13

I'm looking for a way to tell swagger that a certain API response code doesn't have a response body. A get response, for example, that can either return a 200 code with the actual object as a response or a 404 if the object associated with the passed ID doesn't exist:

@ApiResponses(value = {
    @ApiResponse(responseCode = "200", description = "Object found"),
    @ApiResponse(responseCode = "404", description = "Invalid object ID", content = @Content)
})

This is the closest thing I could figure out but it's not perfect, I still get an annoying "Media type" under the description of the 404 response. Thanks!

valmarv
  • 854
  • 1
  • 8
  • 14
  • Why can't you use the responseCode 204? – MOnkey Feb 20 '20 at 11:59
  • What if I want an extra response code, like 403 for example (you are not authorized to access this object)? I want to handle the most important special cases through response codes so users don't have to bother with the response body... – valmarv Feb 20 '20 at 12:13

5 Answers5

12

If you are not specifying the content attribute of @ApiResponse annotation the return type of the controller method will be your response content. To prevent this define content explicitly:

@ApiResponse(responseCode = "200", description = "OK",
             content = @Content(schema = @Schema(implementation = Void.class)))

Or you can simply return ResponseEntity<Void>.

Vladas Maier
  • 2,054
  • 2
  • 22
  • 34
  • Void.class is the default value of the implementation parameter, doesn't help. My method doesn't return void unfortunately. This is what I get: https://ibb.co/6ZDNynR – valmarv Feb 20 '20 at 14:27
  • `implementation = Void.class` seems work with `1.6.13`. – Jin Kwon Dec 05 '22 at 02:34
9

This is probably the better (and shorter) way:

@ApiResponse(
   responseCode = "404", 
   description = "Not found", 
   content = @Content(schema = @Schema(hidden = true))) 
skeeks
  • 359
  • 2
  • 8
2

You can use the following on top of your method in v2

@ApiResponses(value = {
        @ApiResponse(code = 200, message = "Success", response = YourObject.class),
        @ApiResponse(code = 401, message = "Unauthorized"),
        @ApiResponse(code = 403, message="Forbidden"),
        @ApiResponse(code = 404, message = "Not Found"),
        @ApiResponse(code = 500, message = "Failure")
})

For V3, you could try something like this in case your method is returning some object

@Operation(summary = "Add a new object", description = "", tags = { "yourObject" })
@ApiResponses(value = { 
        @ApiResponse(responseCode = "201", description = "Object created",content = @Content(schema = @Schema(implementation = YourObject.class))), 
        @ApiResponse(responseCode = "400", description = "Invalid input"), 
        @ApiResponse(responseCode = "409", description = "Object already exists") })    
        @PostMapping(value = "/your-url", consumes = {"application/json","application/xml" })
        public ResponseEntity<YourObject> addObject(
            ...
            return ...
        }

In case your method is returning void try this one

@Operation(summary = "Update an existing object", description = "", tags = { "yourObject" })
@ApiResponses(value = {
        @ApiResponse(responseCode = "200", description = "successful operation"),
        @ApiResponse(responseCode = "400", description = "Invalid ID supplied"),
        @ApiResponse(responseCode = "404", description = "Object not found"),
        @ApiResponse(responseCode = "405", description = "Validation exception") })  
        @PutMapping(value = "/your-url/{id}", consumes = { "application/json", "application/xml" })  
        public ResponseEntity<Void> addObject(
            ...
            return ...
        }
MOnkey
  • 751
  • 6
  • 13
1

Not sure if it's a feature, but an empty @Content worked for me:

interface MyControllerOpenApiSpec {

    @ApiResponse(responseCode = "200") // shows MyDTO schema
    @ApiResponse(responseCode = "404", content = @Content) // no schema shown
    MyDTO getMyDTO();

}
Lucas Noetzold
  • 1,670
  • 1
  • 13
  • 29
0

There is not any content method; maybe, it is changed.

public @interface ApiResponse {
    int code();

    String message();

    Class<?> response() default Void.class;

    String reference() default "";

    ResponseHeader[] responseHeaders() default {@ResponseHeader(
    name = "",
    response = Void.class
)};

    String responseContainer() default "";

    Example examples() default @Example({@ExampleProperty(
    value = "",
    mediaType = ""
)});
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103