Документация 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.