springdo c несколько ответов 404 с использованием @ApiResponse (java аннотации) - PullRequest
2 голосов
/ 05 августа 2020

Как создать несколько ответов 404 (или, в более широком смысле, несколько ответов с одним и тем же кодом HTTP), используя java аннотации.

Я пробовал:

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

А также несколько @Content:

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

Единственный способ получить что-то похожее на множественное - использовать @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")
        }
    )
)

Это не идеально, потому что это требует человеческого взаимодействия для просмотра всех и просто нежелательно; ожидание должно быть:

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

или даже лучше:

- 200
- 404 Description 1
      Description 2
      Description 3

Я использую springdo c и следующий dep:

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

Ответы [ 2 ]

2 голосов
/ 09 августа 2020

По дизайну, а не Springdo c, а OpenAPI-Specification, все ответы хранятся в типе ApiResponses, который расширяет LinkedHashMap.

Каждый HTTP-код, для операции может быть назначен только один объект ApiResponse.

Использование примеров - хороший способ go. Если ваши несколько ответов 404 имеют разную структуру, вы можете использовать один из следующих:

@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;
    }

}
}
0 голосов
/ 10 августа 2020

Я решил свою проблему, просто добавив тег HTML <br/> к описанию, в котором я хотел новую строку:

@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;
}

Конечно, вы должны принять во внимание @Content, который вы можете легко добавить в аннотацию, но мне это не нужно в моем сценарии, мне просто нужно описание.

Затем в Контроллер можно использовать аннотацию:

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