soulshined
soulshined

Reputation: 10612

springdoc multiple 404 responses using @ApiResponse (java annotations)

How to create multiple 404 responses (or more broadly, multiple same HTTP code responses) using java annotations.

I've tried:

@ApiResponse(
    responseCode = "404",
    description = "Not Found 1"
)
@ApiResponse(
    responseCode = "404",
    description = "Not Found 2"
)

And also mulitple @Content:

@ApiResponse(
    responseCode = "404",
    content = {
        @Content(schema = @Schema(name = "404-1", description = "404-1")),
        @Content(schema = @Schema(name = "404-2", description = "404-2"))
    }
)

The only way I can get something similar to multiple is by using @ExampleObject[]:

@ApiResponse(
    responseCode = "404",
    content = @Content(
        mediaType = "application/json",
        examples = {
            @ExampleObject(name = "404-1", description = "Not Found 1 desc"),
            @ExampleObject(name = "404-2", description = "Not Found 2 desc")
        }
    )
)

This is not ideal because it requires human interaction to view all of them and is just not wanted; the expectation is to have:

- 200
- 404 Description 1
- 404 Description 2
- 404 Description 3

or even better:

- 200
- 404 Description 1
      Description 2
      Description 3

I'm using springdoc and the following dep:

<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-ui</artifactId>
  <version>1.4.3</version>
</dependency>

Upvotes: 4

Views: 4555

Answers (2)

soulshined
soulshined

Reputation: 10612

I solved my issue by just adding an HTML <br/> tag to the description where I wanted a new line:

@Operation(
   responses = {
      @ApiResponse(responseCode = "404", content = @Content,
         description = 
            "This is potential 404 #1 <br/>" +
            "This is potential 404 #2"
      )
   }
)

snapshot

Alternatively,

You could create an annotation to make this more readable, for example something like @ApiResponse404 and add it to the operation via OperationCustomizer:

@Override
public Operation customize(Operation operation, HandlerMethod handlerMethod) {
    ApiResponse404 notFounds = handlerMethod.getMethodAnnotation(ApiResponse404.class);
    if (notFounds != null)
        operation.getResponses()
                 .addApiResponse("404", new ApiResponse()
                                            .description(String.join("<br/>", notFounds.value()))
                                );
    return operation;
}

Of course you would have to take into consideration the @Content, which you can easily add to the annotation, but I don't need it my scenario, I just need the description.

Then in a controller you can use the annotation:

@GetMapping("/helloworld")
@ApiResponse404({"This is potential 404 #1", "This is potential 404 #2"})
String getHelloWorld() {
    return "Hello. World.";
}

Upvotes: 0

brianbro
brianbro

Reputation: 4789

By design, and not springdoc, but OpenAPI-Specification, all the responses are stored in a type ApiResponses which extends LinkedHashMap.

Eeach HTTP code, for an operation can only have one ApiResponse object assigned.

Using examples is a good way to go. If your multiple 404 responses have different structure, you can use oneof as follow:

@RestController
public class HelloController {

@GetMapping("/hello")
@ApiResponses({
        @ApiResponse(responseCode = "200"),
        @ApiResponse(description = "Not found", responseCode = "404",
                content = @Content(mediaType = "application/json", schema = @Schema(oneOf = {
                        Foo.class, Bar.class }))) })
String hello() {
    return null;
}


@Schema(description = "this is bar")
class Bar {
    private String bar;

    public String getBar() {
        return bar;
    }

    public void setBar(String bar) {
        this.bar = bar;
    }

}

@Schema(description = "this is foo")
class Foo {

    private String foo;

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }

}
}

Upvotes: 2

Related Questions