Swagger è un progetto open source utilizzato per generare la documentazione per microservizi. Fornisce un’interfaccia utente per accedere ai nostri servizi web RESTful tramite browser. Per abilitare Swagger nell’applicazione Spring Boot, è necessario aggiungere le seguenti dipendenze nel pom.xml
<!-- SWAGGER 2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency>h <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
Creare una classe contraddistinta dall’annotazione @ EnableSwagger2:
@Configuration
@EnableSwagger2
@Api(value="mioprogetto", tags="controller di test che fa alcune operazioni bla bla")
public class SwaggerConfig
{
/*
* URL Swagger: http://localhost:9100/swagger-ui.html
* Docs: https://swagger.io/docs/
*/
@Bean
public Docket api()
{
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.demo"))
.paths(regex("/api/ciao.*"))
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo()
{
return new ApiInfoBuilder()
.title("ARTICOLI WEB SERVICE API")
.description("Spring Boot REST API per la gestione articoli Prova")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
.contact(new Contact("pinco pallino", "https://dgkdg.it", "pinuccio@gg.it"))
.build();
}
}
Analizziamo il codice:
@Bean
public Docket api()
{
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.demo"))
.paths(regex("/api/ciao.*"))
.build()
.apiInfo(apiInfo());
}
Questo metodo specifica qual’é il package, e l’url, in cui si trovano i nostri servizi.
private ApiInfo apiInfo()
{
return new ApiInfoBuilder()
.title("ARTICOLI WEB SERVICE API")
.description("Spring Boot REST API per la gestione articoli Prova")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0")
.contact(new Contact("pinco pallino", "https://dgkdg.it", "pinuccio@gg.it"))
.build();
}
La classe ApiInfo contiene le informazioni generali dei nostri servizi.
In cima alla classe c’è l’annotation
@Api(value="mioprogetto", tags="controller di test che fa alcune operazioni bla bla")
public class SwaggerConfig
{
Che ci fornisce informazioni di massima su cosa fa questo micro servizio. Questa info la vedremo in cima alla nostra documentazione.
Analizziamo ora il controller.
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@RestController
@CrossOrigin(origins = "http://localhost:4200")
@Api(value = "HelloWorldSpringBootSwagger", tags = "Controller di prova ")
@RequestMapping("/api")
public class HelloController {
@ApiModelProperty(notes = "codice del nostro articolo")
private String codice;
// ------------------- Ricerca Per Codice ------------------------------------
@ApiOperation(value = "Ricerca articolo per codice", notes = "Restituisce i dati dell'articolo in formato JSON", response = String.class, produces = "application/json")
@ApiResponses(value = { @ApiResponse(code = 200, message = "L'articolo cercato è stato trovato!"),
@ApiResponse(code = 404, message = "L'articolo cercato NON è stato trovato!"),
@ApiResponse(code = 403, message = "Non sei AUTORIZZATO ad accedere alle informazioni"),
@ApiResponse(code = 401, message = "Non sei AUTENTICATO") })
@RequestMapping(value = "/ciao", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> helloWorld()
{
System.out.println("****** dentro *******");
return new ResponseEntity<String>("ciao mamma", HttpStatus.OK);
}
// ------------------- Ricerca Per Codice ------------------------------------
@ApiOperation(value = "Ricerca articolo per codice", notes = "Restituisce i dati dell'articolo in formato JSON", response = String.class, produces = "application/json")
@ApiResponses(value = { @ApiResponse(code = 200, message = "L'articolo cercato è stato trovato!"),
@ApiResponse(code = 404, message = "L'articolo cercato NON è stato trovato!"),
@ApiResponse(code = 403, message = "Non sei AUTORIZZATO ad accedere alle informazioni"),
@ApiResponse(code = 401, message = "Non sei AUTENTICATO") })
@RequestMapping(value = "/ciaoDue", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> helloWorld(@ApiParam("codice articolo") @PathVariable("codice") String codice)
{
System.out.println("****** dentro *******");
return new ResponseEntity<String>("ciao mamma", HttpStatus.OK);
}
}
Su ogni metodo aggiungiamo le seguenti annotation:
// ------------------- Ricerca Per Codice ------------------------------------
@ApiOperation(value = "Ricerca articolo per codice", notes = "Restituisce i dati dell'articolo in formato JSON", response = String.class, produces = "application/json")
@ApiResponses(value = { @ApiResponse(code = 200, message = "L'articolo cercato è stato trovato!"),
@ApiResponse(code = 404, message = "L'articolo cercato NON è stato trovato!"),
@ApiResponse(code = 403, message = "Non sei AUTORIZZATO ad accedere alle informazioni"),
@ApiResponse(code = 401, message = "Non sei AUTENTICATO") })
@RequestMapping(value = "/ciao", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> helloWorld()
che ci informano su cosa fa l’operazione, e i vari codici di risposta che possiamo ottenere.
Se il metodo ha in ingresso un parametro, lo possiamo documentare con @ApiParam(“codice articolo”)
Esempio
// ------------------- Ricerca Per Codice ------------------------------------
@ApiOperation(value = "Ricerca articolo per codice", notes = "Restituisce i dati dell'articolo in formato JSON", response = String.class, produces = "application/json")
@ApiResponses(value = { @ApiResponse(code = 200, message = "L'articolo cercato è stato trovato!"),
@ApiResponse(code = 404, message = "L'articolo cercato NON è stato trovato!"),
@ApiResponse(code = 403, message = "Non sei AUTORIZZATO ad accedere alle informazioni"),
@ApiResponse(code = 401, message = "Non sei AUTENTICATO") })
@RequestMapping(value = "/ciaoDue", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> helloWorld(@ApiParam("codice articolo") @PathVariable("codice") String codice)
{
System.out.println("****** dentro *******");
return new ResponseEntity<String>("ciao mamma", HttpStatus.OK);
}
Possiamo anche documentare, oltre ai controlller, anche ad esempio le classi model. Per fare questo usiamo l’annotation @ApiModelProperty
Esempio
public class Articolo {
// @Id
// @Column(name = "CODICE")
@ApiModelProperty(notes = "Codice Articolo")
private int codice;
public int getCodice() {
return codice;
}
public void setCodice(int codice) {
this.codice = codice;
}
}
Avviamo il servizio e vediamo ora che cosa otterremo con queste annotation.
Dal log notiamo
Mapped URL path [/v2/api-docs] onto method [springfox.documentation.swagger2.web.Swagger2Controller#getDocumentation(String, HttpServletRequest)]
Questo path (v2/api-docs) è quello che dobbiamo richiamare per ottenere la nostra documentazione in formato json
http://localhost:8080/v2/api-docs

Questo formato, anche se leggibile, non è comodo, ma swagger ci fornisce anche una interfaccia grafica consultabile da browser ad uno specifico indirizzo
http://localhost:8080/swagger-ui.html

Questa è la documentazione generata.
Notiamo che è presente anche l’elenco dei metodi generati

con tutte le info che abbiamo inserito


