in swagger swagger ui documentation java spring api rest ~ temps de lecture.

Documenter vos APIs REST avec Swagger

Développer une API REST grand public c'est bien mais encore faut-il que vos consommateurs/clients sachent intéragir avec vos services exposés.
Il faut donc passer du temps à décrire chaque Service Web en expliquant comment l'interroger et récupérer les informations dont vous avez besoin.
C'est un travail long et fastidieux mais nécessaire, et heureusement de nombreux outils ont été créés dans cet unique but, en voici trois :

La suite du billet portera sur Swagger et son intégration dans un projet Java Spring MVC.

Swagger

Le but de Swagger est de définir un standard de description d'APIs REST, afin de rendre accessible et compréhensible de tous (robots et humains) les services mis à disposition et la façon de les utiliser sans avoir accès au code source.
Swagger va au delà d'une simple documentation technique car il permet à un consommateur (quel qu'il soit) l'utilisation à distance des services afin d'en explorer toutes les capacités :

  • savoir quel verbe HTTP utilisé
  • savoir quelles données fournir en entrée
  • savoir interpréter le code statut de retour
  • ...

Swagger

Voici un exemple de fichier descriptif Swagger en YAML d'une API REST et d'un de ses services :

swagger: '2.0'  
info:  
  title: Magic Supremacy API
  description: Les cartes et les decks Magic l'Assemlée
  version: "1.0.0"
host: api.xxxxx.com  
schemes:  
  - https
basePath:  
produces:  
  - application/json
paths:  
  /cards:
    get:
      summary: All Cards
      description: |
        Permet de lister l'ensemble des cartes Magic l'Assemblée par le biais de filtres et de pagination.
      parameters:
        - name: color
          in: query
          description: Couleur.
          required: false
          type: text
        - name: manacost
          in: query
          description: Coût total en mana.
          required: false
          type: number
          format: double
      tags:
        - Cards
      responses:
        200:
          description: An array of cards
          schema:
            type: array
            items:
              $ref: '#/definitions/Card'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'

Démonstration en ligne de l'outil : Swagger Editor

Swagger Core

Au delà de définir un standard de description d'API REST, Swagger offre aussi des outils permettant de générer ce fichier à partir du code source de votre projet Java par exemple (d'autres langages sont aussi supportés), avec sa bibliothèque Swagger Core.

Que cela veut-il dire ?

En tant que développeur d'applications web, vous écrivez comme d'habitude vos services web avec votre framework préféré (Spring MVC, Jersey, RESTEasy ...), Swagger scanne votre code et génère pour vous le fameux fichier de description standardisé et le rend accessible au format JSON via une url spécifique (exemple pour la v2 de Swagger: http: //votre-api-url/v2/api-docs).

Vous n'avez presque plus rien à faire si ce n'est d'ajouter la dépendance Swagger à votre projet et le configurer un minimum selon votre framework utilisé, c'est beau.

Voici un exemple de fichier de configuration Java pour le framework Spring MVC utilisé à travers Spring Boot :

<dependency>  
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.4.0</version>
</dependency>  
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {

    @Autowired
    private ApiProperties apiProperties;

    /**
     * Swagger Springfox configuration.
     */
    @Bean
    public Docket swaggerSpringfoxDocket() {
        // @formatter:off
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .select()
                    .apis(RequestHandlerSelectors.basePackage("package.des.services.web.de.mon.api"))
                    .paths(PathSelectors.any())
                    .build()
                .pathMapping("/")
                .directModelSubstitute(LocalDate.class, String.class)
                .genericModelSubstitutes(ResponseEntity.class)
                .useDefaultResponseMessages(false)
                .enableUrlTemplating(true)
                .forCodeGeneration(true)
                .apiInfo(metadata());
        // @formatter:on

        return docket;
    }

    private ApiInfo metadata() {
        return new ApiInfoBuilder()
                .title(apiProperties.getSwagger().getTitle())
                .description(apiProperties.getSwagger().getDescription())
                .version(apiProperties.getSwagger().getVersion())
                .contact(contact())
                .build();
    }

    private Contact contact() {
        return new Contact(apiProperties.getSwagger().getContact(), "", "");
    }

}

Swagger UI

Une première étape vient d'être franchie avec cette documentation auto-générée mais Swagger va encore plus loin en proposant un outil qui va permettre de rendre "human readable" ce fichier JSON indigeste, en générant des pages HTML à partir du contenu de ce fichier.
Il permet ainsi une meilleure visualisation des services exposés et surtout une utilisation à distance de l'ensemble de votre API.

Ce mini site web généré par Swagger UI ne possède aucune dépendance (les fichiers HTML/JS/CSS générés suffisent à eux-mêmes) et permet donc d'être hébergé sur n'importe quel serveur ou machine locale. Il est accessible par défaut à l'adresse suivante : http ://votre-api-url/swagger-ui.html.

Démonstration ici pour vous rendre compte de la chance que nous avons ^^

Il vous suffit d'ajouter la dépendance suivante à votre projet et le tour est joué.

<dependency>  
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.4.0</version>
</dependency>  

Aller plus loin

Si vous voulez affiner le contenu récupéré automatiquement par Swagger en scannant votre code source, il est possible d'utiliser un certain nombre d'annotations au niveau de services web.
Voici un bref aperçu de ce qui est possible de faire et le lien vers la documentation officielle.

Name    Description  
@Api    Marks a class as a Swagger resource.
@ApiImplicitParam    Represents a single parameter in an API Operation.
@ApiImplicitParams    A wrapper to allow a list of multiple ApiImplicitParam objects.
@ApiModel    Provides additional information about Swagger models.
@ApiModelProperty    Adds and manipulates data of a model property.
@ApiOperation    Describes an operation or typically a HTTP method against a specific path.
@ApiParam    Adds additional meta-data for operation parameters.
@ApiResponse    Describes a possible response of an operation.
@ApiResponses    A wrapper to allow a list of multiple ApiResponse objects.
@Authorization    Declares an authorization scheme to be used on a resource or an operation.
@AuthorizationScope    Describes an OAuth2 authorization scope.
@ResponseHeader    Represents a header that can be provided as part of the response.
comments powered by Disqus