Reputation: 10612
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
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"
)
}
)
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
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