Aller au contenu

Swagger 3.0 avec Spring Boot

Pinard04Swagger exemple

une Open API Specification avec Swagger 3.0, un outil bien pratique pour générer une page HTML permettant de documenter et d’effectuer des requêtes en JSON pour tester en toute simplicité son API back en Spring ou Spring Boot.

https://swagger.io/tools/swagger-ui/

1. Ajouter une dépendance

	implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'

2. Modifier le fichier application.properties

Non obligatoire, mais ça évite un bug !

# Swagger
spring.mvc.pathmatch.matching-strategy = ANT_PATH_MATCHER

3. Ajouter une annotation dans votre classe de lancement

Voici ci-dessous la classe en entier avec les bonnes importations (de l’exemple Pinard04Swagger):

package fr.pinard;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;

@SpringBootApplication
@OpenAPIDefinition(info = @Info(title = "Pinard04Swagger API", version = "3.0", description = "Démo Swagger 3.0"))
public class Pinard04SwaggerApplication {

	public static void main(String[] args) {
		SpringApplication.run(Pinard04SwaggerApplication.class, args);
	}

}

Pour information, voici le contenu de la classe contrôleur qui sert d’exemple :

package fr.pinard.controller;

import java.util.Collection;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import fr.pinard.model.Vin;
import fr.pinard.model.VinPK;
import fr.pinard.repository.VinRepository;

/**
 * @author Philippe
 *
 */
@RestController
@CrossOrigin("*")
public class PinardController {

	@Autowired
	private VinRepository vinRepository;

	@GetMapping("/accueil")
	@ResponseBody
	public String home(){

		StringBuilder sb = new StringBuilder();
		sb.append("<h1>Regardez dans votre console et dans votre base de données MySQL <strong>JPA</strong></h1>");
		sb.append("<ul><li><a href='http://localhost:8080/vins'>Voir la liste des vins enregistrés</a></li>");
		sb.append("<li><a href='http://localhost:8080/swagger-ui/index.html'>Avec Swagger 3.0</a></li></ul>");
		return  sb.toString();
	}


	/**
	 * Recherche d'un vin par son identifiant et sa désignation
	 * @param id
	 * @param designation
	 * @return
	 */
	@GetMapping("/vin/{id}/{designation}")
	public Optional<Vin> findById(@PathVariable("id") Integer id, @PathVariable("designation") String designation){
		return vinRepository.findById(new VinPK(id, designation));
	}
	/**
	 * Retourne tous les vins stockés en BD
	 * @return collection de Vins
	 */
	@GetMapping("/vins")
	public Collection<Vin> findAll(){

		return vinRepository.findAll();
	}
	/**
	 * Ajoute un Vin en BD
	 * @param vin
	 * @return
	 */
	@PostMapping("/vin/post")
	public Vin ajoutVin(@RequestBody Vin vin){
		return vinRepository.save(vin);
	}
	/**
	 * Met à jour un Vin
	 * @param vin
	 * @return
	 */
	@PutMapping("/vin/put")
	public Vin updateVin(@RequestBody Vin vin){
		return vinRepository.save(vin);
	}


	/**
	 * Met à jour la quantité d'un Vin grâce à l'identifiant passé en paramètre
	 * @param id
	 * @param designation
	 * @param quantite
	 */
	@PutMapping("/vin/{id}/{designation}/{quantite}")
	public void updateQuantite(@PathVariable("id") Integer id,
			@PathVariable("designation") String designation,
			@PathVariable("quantite") int quantite){
		(vinRepository.getReferenceById(new VinPK(id, designation))).setQuantite(quantite);
	}


}

4. Ajouter un fichier de Configuration spécifique dans le package principal

La page principale de configuration de swagger.

package fr.pinard;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;


@Configuration
public class SwaggerConfig {

    @Bean
    public Docket api() {

        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiEndPointsInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiEndPointsInfo() {

        return new ApiInfoBuilder().title("Pinard04Swagger REST API")
                .license("Apache 2.0")
                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
                .version("1.0-SNAPSHOT")
                .build();
    }
}

Securité (uniquement si votre application intègre JWT)

Si vous utilisez JWT, il faut autoriser des ressources pour swagger et l’accès à swagger-ui.

http.authorizeRequests()//
                ... // liste des pages autorisées ou interdites
                .antMatchers("/v2/api-docs", "/webjars/**", "/swagger-resources/**", "/configuration/**", "/swagger-ui.html/**").permitAll()

                // Disallow everything else...
                .anyRequest().authenticated();

http.headers().frameOptions().disable(); // Il faut aussi ajouter cette ligne, car la console s'affiche dans des frames.

Vérification après avoir lancé votre application Spring Boot

Normalement c’est ok. Vous pouvez maintenant vous rendre à l’adresse : http://localhost:8080/swagger-ui/index.html

Pinard04Swagger exemple

Projet Démo Pinard04Swagger sur GitHub

@author Philippe Bouget