Документация Swagger для Spring Палитра интерфейса

Я разработал микросервис с помощью Spring Boot. Документация по REST API сделана с помощью Swagger. Некоторые ресурсы REST используют концепции Spring для бесплатной нумерации страниц. Ниже приведен пример:

@RequestMapping(value = "/buckets", method = GET)
public PagedResources list(Pageable pageable, PagedResourcesAssembler assembler) {
    return bucketService.listBuckets(pageable, assembler);
}

Если я открою страницу Swagger, для ресурса будет доступна следующая форма:

enter image description here

У меня проблема в том, что параметр pageable обнаруживается с помощью типа содержимого application/json, и я не знаю, как передать значение, например, для изменения размера страницы. Все значения, кажется, игнорируются.

Можно ли передать параметры запроса в виде объекта JSON? или можно настроить Swagger для генерации независимых полей параметров запроса для геттеров, содержащихся в интерфейсе Pageable?

Обратите внимание, что я использую Springfox с Gradle:

compile 'io.springfox:springfox-spring-web:2.3.1'
compile 'io.springfox:springfox-swagger2:2.3.1'
compile 'io.springfox:springfox-swagger-ui:2.3.1'

Ответ 1

Это известная проблема с Spring -Fox. См. Проблема # 755. На основе zdila comment 2 в настоящее время альтернативой является добавление @ApiImplicitParams, который не идеален, но он действительно работает.

@ApiImplicitParams({
    @ApiImplicitParam(name = "page", dataType = "integer", paramType = "query",
            value = "Results page you want to retrieve (0..N)"),
    @ApiImplicitParam(name = "size", dataType = "integer", paramType = "query",
            value = "Number of records per page."),
    @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query",
            value = "Sorting criteria in the format: property(,asc|desc). " +
                    "Default sort order is ascending. " +
                    "Multiple sort criteria are supported.")
})

[Swagger UI showing @ApiImplicitParams for Pageable]

1 https://github.com/springfox/springfox/issues/755

2 https://github.com/springfox/springfox/issues/755#issuecomment-135059871

Ответ 2

Основываясь на ответе Vineet Bhatia, вы можете заключить решение в пользовательскую аннотацию для повторного использования:

@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@ApiImplicitParams({
    @ApiImplicitParam(name = "page", dataType = "int", paramType = "query", value = "Results page you want to retrieve (0..N)"),
    @ApiImplicitParam(name = "size", dataType = "int", paramType = "query", value = "Number of records per page."),
    @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query", value = "Sorting criteria in the format: property(,asc|desc). "
            + "Default sort order is ascending. " + "Multiple sort criteria are supported.") })
@interface ApiPageable {
}

Который затем можно использовать так:

@ApiPageable
public Page<Data> getData(Pageable pageRequest) {

Ответ 3

Ответ Vineet Bhatia с @ApiImplicitParams выглядит отлично. Но я столкнулся с ситуацией, когда @ApiIgnor и @ApiParam(hidden = true) не работают, и вы все равно можете наблюдать параметры asembler и pageable. Я исправил эту проблему, добавив следующую строку

docket.ignoredParameterTypes(Pageable.class, PagedResourcesAssembler.class);

в Docket bean в моем SwaggerConfig.

Ответ 4

Ответ Vineet Bhatia будет иметь проблему проверки, если вы не работаете на localhost. Он будет утверждать, что для целочисленных параметров они не соответствуют json-схеме.

Итак, я изменил целое число на строку:

    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", dataType = "string", paramType = "query",
                value = "Results page you want to retrieve (0..N)"),
        @ApiImplicitParam(name = "size", dataType = "string", paramType = "query",
                value = "Number of records per page."),
        @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query",
                value = "Sorting criteria in the format: property(,asc|desc). " +
                        "Default sort order is ascending. " +
                        "Multiple sort criteria are supported.")
})

Ответ 5

Для людей, которые хотят решить эту проблему в 2019 году. Эта конфигурация через документацию Springfox работает нормально, за исключением того, что вы не можете задать описание для параметров.

Код здесь.

https://github.com/springfox/springfox/blob/ef1721afc4c910675d9032bee59aea8e75e06d27/springfox-data-rest/src/main/java/springfox/documentation/spring/data/rest/configuration/SpringDataRestConfiguration.java

Ответ 6

Ответ на вопрос о валидации указан Евгением.

Использование

@ApiImplicitParams({
    @ApiImplicitParam(name = "page", dataType = "int", paramType = "query", value = "Results page you want to retrieve (0..N)"),
    @ApiImplicitParam(name = "size", dataType = "int", paramType = "query", value = "Number of records per page."),
    @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query", value = "Sorting criteria in the format: property(,asc|desc). "
            + "Default sort order is ascending. " + "Multiple sort criteria are supported.") })

выдает исключение:

Illegal DefaultValue  for parameter type integer
java.lang.NumberFormatException: For input string: ""
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
    at java.base/java.lang.Long.parseLong(Long.java:709)
    at java.base/java.lang.Long.valueOf(Long.java:1151)
    at io.swagger.models.parameters.AbstractSerializableParameter.getExample(AbstractSerializableParameter.java:412)
    at jdk.internal.reflect.GeneratedMethodAccessor366.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:688)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119)
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79)

(по крайней мере, в случае с springfox-swagger2 и springfox-swagger2-ui версии 2.9.2)

Вы можете избежать исключения, следуя ответу Евгения или добавив значения по умолчанию и примеры значений для целочисленных параметров:

@ApiImplicitParams({
    @ApiImplicitParam(name = "page", dataType = "int", paramType = "query", value = "Results page you want to retrieve (0..N)", defaultValue = "0", example = "2"),
    @ApiImplicitParam(name = "size", dataType = "int", paramType = "query", value = "Number of records per page.", defaultValue = "20", example = "10"),
    @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query", value = "Sorting criteria in the format: property(,asc|desc). "
            + "Default sort order is ascending. " + "Multiple sort criteria are supported.") })

Ответ 7

Хотя решение с неявными параметрами работает, оно вводит много лишнего хрупкого кода. В итоге мы пошли со следующим решением:

@GetMapping(value = "/")
public HttpEntity<PagedResources<Item>> getItems(
    @RequestParam(value = "page", required = false) Integer page,
    @RequestParam(value = "size", required = false) Integer size,
    PagedResourcesAssembler assembler) {
    Page<Item> itemPage = itemService.listItems(PageRequest.of(page, size, Sort.unsorted()));
    return new ResponseEntity<>(assembler.toResource(itemPage), HttpStatus.OK);
}

Мы передаем PageRequest (который реализует Pageable) нашему сервису, который возвращает Page. (все из org.springframework.data.domain).

org.springframework.data.web.PagedResourcesAssembler внедряется с помощью метода контроллера и позволяет отображать элементы в org.springframework.hateoas.PagedResources

Нам не требовалась динамическая сортировка, поэтому мы ее опускали; добавление сортировки сопряжено с некоторыми трудностями, поскольку springfox плохо работает с org.springframework.data.domain.Sort.