web-dev-qa-db-fra.com

Documentation Swagger pour l'interface Spring Pageable

J'ai développé un microservice en utilisant Spring Boot. La documentation de l'API REST est faite avec Swagger. Certaines ressources REST utilisent les concepts de Spring pour permettre la pagination gratuitement. En voici un exemple:

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

Si j'ouvre la page Swagger, le formulaire suivant est disponible pour la ressource:

 enter image description here

Le problème que j'ai est que le paramètre pageable est détecté avec content-type application/json et je ne sais pas comment passer une valeur pour changer la taille de la page par exemple. Toutes les valeurs semblent être ignorées.

Est-il possible de transmettre les paramètres de requête en tant qu'objet JSON? ou est-il possible de configurer Swagger pour générer des champs de paramètres de requête indépendants pour les accesseurs contenus dans l'interface Pageable? 

Veuillez noter que j'utilise Springfox avec 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'
16
Laurent

Ceci est un problème connu avec Spring-Fox. Voir le numéro # 755 . D'après le commentaire de zdila 2 , à ce moment-là, la solution consiste à ajouter @ApiImplicitParams, ce qui n'est pas idéal, mais cela fonctionne.

@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]

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

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

23
Vineet Bhatia

La réponse de Vineet Bhatia avec @ApiImplicitParams est satisfaisante. Mais j’ai fait face à une situation où @ApiIgnor et @ApiParam(hidden = true) ne fonctionnaient pas et que vous pouviez toujours observer les paramètres asembler et pageable. J'ai corrigé ce problème en ajoutant la ligne suivante

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

au haricot Docket dans ma SwaggerConfig.

5
Mykola Lavrenko

En vous appuyant sur la réponse de Vineet Bhatia, vous pouvez envelopper la solution dans une annotation personnalisée pour la réutiliser:

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

Ce qui peut alors être utilisé comme suit:

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

La réponse de Vineet Bhatia aura un problème de validation lorsque tu ne cours pas sur localhost. Cela fera valoir pour les paramètres entiers qu'ils ne correspondent pas au schéma json.

J'ai donc changé de nombre entier en chaîne:

    @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.")
})
2
Evgeny Konurbaev

Bien que la solution avec les paramètres implicites fonctionne, elle introduit beaucoup de code supplémentaire et fragile. Finalement nous sommes allés avec la solution suivante:

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

Nous transmettons une PageRequest (qui implémente Pageable) à notre service, qui renvoie une Page. (tous de org.springframework.data.domain).

Le org.springframework.data.web.PagedResourcesAssembler est injecté automatiquement par la méthode du contrôleur et permet de mapper des éléments sur org.springframework.hateoas.PagedResources

Nous n'avions pas besoin de tri dynamique, nous l'avons donc omis. Il est difficile d'ajouter un tri car springfox ne joue pas à Nice avec org.springframework.data.domain.Sort.

0
Adriaan Koster