Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Java Spring
  3. Documentation Spring REST Docs
Extrait - Java Spring Le socle technique des applications Jakarta EE (4e édition)
Extraits du livre
Java Spring Le socle technique des applications Jakarta EE (4e édition) Revenir à la page d'achat du livre

Documentation Spring REST Docs

Introduction

Les applications s’ouvrent et s’interconnectent de plus en plus. Elles exposent et partagent leurs états via des interfaces qui sont, aujourd’hui, souvent des interfaces sous forme d’API REST avec des microservices. Ces interfaces doivent être documentées afin de faciliter l’accès à nos applications.

La documentation des API publiques LinkedIn, Facebook, Twitter, Google est particulièrement bien faite et elle est parfois comparée à la documentation de nos API en interne et cela nous pousse à passer un temps considérable pour avoir une documentation claire, précise et à jour.

Pour répondre à ce besoin, Spring a mis à disposition une librairie Spring REST Docs qui peut être utilisée pour créer une documentation automatique pour les services REST. Cette possibilité vient en complément des outils comme Swagger (statique et dynamique) avec SpringFox et le HAL Browser qui montrent par l’exemple le fonctionnement des services.

La librairie se base sur Asciidoctor et des extraits de documentation pour générer automatiquement, à la compilation, du texte brut ou du HTML.

Asciidoctor est très puissant pour créer des documentations.

Il est aussi possible de générer du Markdown (fichier *.md) qu’il est alors très pratique d’utiliser dans GitLab ou GitHub par exemple. La librairie est utilisée conjointement avec des librairies de tests comme jUnit et TestNG. La librairie utilise les tests pour produire la documentation relative aux extraits pour les requêtes et les réponses. Elle documente des API en se basant sur l’exécution des tests, ce qui garantit que l’API est à jour et que les exemples qu’elle montre fonctionnent.

La documentation se concentre sur les ressources du service REST et détaille d’une part les requêtes HTTP que consomme l’API et d’autre part les réponses qu’elle produit tout en gardant masquée la partie implémentation.

Dans les sections suivantes, nous utiliserons Maven, mais il est aussi possible de faire l’équivalent avec Gradle. De même, nous ne verrons que partiellement la documentation produite, car elle est très complète. L’exemple du chapitre permet...

Exemple JUnit 5 (Jupiter)

La documentation de l’exemple est générée dans le répertoire target/generated-snippets. Il serait possible de spécifier un autre répertoire.

Code de mockMvc

Le mock est celui qui est utilisé par Spring REST Docs pour générer la documentation. Il est relativement complexe. L’idéal est d’utiliser l’exemple qui est en téléchargement pour suivre les indications.

private MockMvc mockMvc;  
 
@ExtendWith(RestDocumentationExtension.class)  
  public class JUnit5ExampleTests {  
 
  private MockMvc mockMvc;  
 
  @BeforeEach  
  public void setUp(WebApplicationContext webApplicationContext, 
  RestDocumentationContextProvider restDocumentation) {  
    this.mockMvc =  
       MockMvcBuilders.webAppContextSetup(webApplicationContext) 
         .apply(documentationConfiguration(restDocumentation))  
         .build();  
} 

Appel du service :

this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) 
  .andExpect(status().isOk())  
  .andDo(document("index")); 

Lors des builds, l’outil génère des extraits...

Requête et réponse

Un corps de la requête par défaut est généré dans le fichier request-description.adoc. 

Celui de la réponse dans response-description.adoc.

Pour un Body :

{  
  "contact": {   
    "name": "Jane Doe",  
    "email": "jane.doe@example.com"  
  }  
} 

Nous pouvons configurer ainsi :

this.mockMvc.perform(get("/user/5") 
.accept(MediaType.APPLICATION_JSON)) 
  .andExpect(status().isOk())  
  .andDo(document("index",  
  responseFields(  
    fieldWithPath("contact.email")  
    .description("The user's email address"), [...] 

La requête est présentée sous la forme d’un tableau ayant pour extrait le fichier request-fields.adoc.

Nous pouvons aussi utiliser des chemins JSON.

Il est aussi possible de préciser le type du champ via le type (Object) de la classe FieldDescriptor.

.andDo(document("index",  
  responseFields(  
  fieldWithPath("contact.email").type(JsonFieldType.STRING)  
    .description("The user's email address")))); 

Réponse avec un JSON imbriqué

Nous pouvons avoir une réponse avec un JSON imbriqué.

Pour une description comme ceci :

{  
  "weather": { +  
    "wind": { +  
    "speed": 15.3, +  
    "direction": 287.0 +  
   },  
  "temperature": {  
    "high": 21.2,  
    "low": 14.8  
    }  
  }  
} 

Nous pouvons avoir ce code :

this.mockMvc.perform(get("/locations/1").accept(MediaType. 
APPLICATION_JSON)) +  
.andExpect(status().isOk()).andDo(document("location", +  
responseBody(beneathPath("weather.temperature"))));  
 
Identifieur : beneath-$\{path}.  
 
Snippet : response-description-beneath-weather.temperature.adoc   

Code :  

responseBody(beneathPath("weather.temperature")
.withSubsectionId("temp"));  

Documentation des champs :  

this.mockMvc.perform(get("/locations/1").accept(MediaType.  
APPLICATION_JSON)) +  
.andExpect(status().isOk()) +  
.andDo(document("location", +  
responseFields(beneathPath("weather.temperature"), +  
fieldWithPath("high").description( +  
"The forecast high in degrees celcius"), +  
fieldWithPath("low") +  
.description("The forecast low in degrees celcius")))); 

1. Les paramètres de requête

Nous utilisons la méthode...

Personnalisation de la documentation

Il est possible de prendre en compte les contraintes sur les données (validateurs) pour compléter la documentation et de personnaliser les requêtes et les réponses pour qu’elles collent exactement à l’API. Un exemple dans les exemples téléchargeables montre ces possibilités.

Utilisation de @AutoConfigureRestDocs

Cette annotation peut être appliquée à une classe de test pour activer et configurer la génération automatique des documents Spring REST. Elle permet la configuration du répertoire de sortie, du schéma et du port des URI générés. Lorsqu’une configuration supplémentaire est requise, un bean RestDocsMockMvcConfigurationCustomizer peut être utilisé.

Couplage Swagger 2

Nous avons vu qu’une documentation statique était nécessaire et facile à faire avec Spring et que nous pouvions utiliser le navigateur HAL pour exposer les API. Il est aussi possible d’utiliser Swagger 2. Cette section décrit deux utilisations de Swagger 2 dans les projets Spring : une utilisation standard avec Swagger 2 et une utilisation plus avancée avec SpringFox.

Swagger permet une génération statique à la compilation et SpringFox une génération dynamique à l’exécution. Nous utilisons parfois les deux conjointement.

1. Utilisation Springfox

Nous allons voir comment utiliser, en alternative à la solution étudiée, l’implémentation Springfox sur notre projet d’exemple.

http://springfox.github.io/springfox/docs/current/

Le projet Springfox automatise la documentation des API JSON pour les API construites avec Spring.

Dépendance Maven :

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

Cette classe...

Utilisation avec Spring Data Rest

Nous pouvons utiliser Springfox avec Spring Data Rest. Il suffit d’importer les modèles via l’annotation @Import. Vous pourrez consulter le code complet, qui est trop volumineux pour être reproduit dans son intégralité ici, dans les exemples téléchargeables.

Configuration Java :

@Import(\{ ...  
springfox.documentation.spring.data.rest.configuration.SpringDataRest 
Configuration.class,  
...})  
 
@Import(\{ ...  
springfox.bean.validators.configuration.BeanValidatorPlugins 
Configuration.class,  
...}) 

L’utilisation est donc simple et il est possible de personnaliser beaucoup d’éléments dans la page swagger de documentation de l’application.

Récapitulatif sur la documentation générée

Spring REST Docs peut donc servir à générer la documentation statique d’un projet. Il permet d’avoir une documentation à jour. Asciidoctor peut aussi être utilisé en complément pour générer d’autres parties de la documentation ou pour mutualiser des éléments entre plusieurs documentations comme la documentation des API, du projet, le manuel utilisateur.

Points clés

  • Spring REST Docs peut donc servir à générer la documentation statique d’un projet.

  • Asciidoctor peut aussi être utilisé en complément pour générer d’autres parties de la documentation ou pour mutualiser des éléments entre plusieurs documentations comme la documentation des API, du projet, le manuel utilisateur.

  • Avec ces outils, il est possible d’avoir une documentation de style professionnelle sans y passer trop de temps.