Documentando API Rest com Swagger: Contract Last

Nos últimos anos o universo de API Rest vêm ganhando cada vez mais a atenção de empresas e desenvolvedores para integração entre sistemas internos e externos.

Com o constante aumento no número de API’s Rest desenvolvidas, passou a existir uma preocupação em documentar essas API’s para que desenvolvedores e clientes possam conhecer, de forma padronizada, as funcionalidades dessas Api’s, além de outros detalhes como as URL’s para invocar os recursos, métodos HTTP utilizados, tipos de dados que são passados ao invocar um recurso, o tipo e formato de resposta do serviço, tratamentos de erros, dentre outros detalhes que possam ser importantes no contexto de negócio.

Podemos criar a documentação de uma API Rest por meio de duas abordagens diferentes: Contract First (Api Fisrt) e Contract Last. A primeira abordagem implica em criar a documentação da API Rest e a partir dessa documentação os serviços são construídos. Com base nessa documentação, os clientes da API também podem iniciar seus trabalhos de forma a ganhar produtividade. No blog da MATERA temos um post escrito sobre essa abordagem, para ler basta acessar o link: Swagger: Como gerar uma Documentação Interativa pra API REST

Nesse post, vamos analisar a abordagem Contract Last, onde já temos uma API Rest implementada, sem nenhuma documentação, e a partir desta API vamos gerar uma documentação utilizando a ferramenta Swagger.

Swagger é uma ferramenta que auxilia o desenvolvedor de API’s Rest a criar a documentação das suas API’s de forma padronizada, facilitando o entendimento de cada serviço existente na API e sua estrutura, sem que haja a necessidade de abrir seu código-fonte.

Além disso, através da própria documentação gerada pelo Swagger é possível realizar testes rápidos dos serviços recebendo de forma imediata retorno das chamadas realizadas.

Criando a documentação da API REST com Swagger

Para gerar a documentação de uma API Rest primeiramente precisamos adicionar as dependências do Swagger no pom.xml do projeto, como mostra a Listagem 1.

       <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.0.1</version>
        </dependency>
Listagem 1: Configuração das dependências do spring fox no maven

Como podemos observar na Listagem 1, adicionamos duas dependências no projeto relacionadas a uma biblioteca chamada SpringFox. Mas afinal, para que serve essa biblioteca?

SpringFox é uma suíte de bibliotecas utilizada para integrar o Swagger com o Spring MVC de modo a gerar de forma automática a documentação de API’s Rest escritas em Spring Framework. O SpringFox, disponibiliza uma série de anotações que podem ser empregadas nas classes onde estão implementados os serviços Rest. Por meio dessas anotações o Swagger é capaz de em tempo de execução gerar a documentação de nossa API Rest

Depois de configuradas as dependências do Maven, temos que realizar mais algumas configurações no Spring para que tudo funcione corretamente. O arquivo de configuração do Spring application-context.xml deve estar configurado como mostra a Listagem 2.

 <beans>
	 <!-- Indica quais pacotes o Spring deve escanear em busca de componentes -->
	 <context:component-scan base-package="com.projeto" />

	 <!-- Permite ao spring identificar classe anotadas com @Controller -->
 	 <mvc:annotation-driven enable-matrix-variables="true" />

     <!-- Habilita o swagger ui -->
    <mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/" />
     <mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>

     <!-- Inclui uma configuração personalizada do swagger-->
     <bean name="swagger2DocumentationConfiguration" class="springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration" />
    
     <!-- Bean para alterar as informações gerais da API. -->
    <bean name="applicationSwaggerConfig" class="com.projeto.configuracao.ApplicationSwaggerConfig"/>
 </beans>
Listagem 2: Configuração do application-context.xml

Na configuração do application-context.xml, da Listagem 2, mostramos como é realizada a configuração do Swagger para gerar a documentação da API Rest. Com base nesse arquivo, devemos nos atentar para as seguintes configurações:

   <bean name="swagger2DocumentationConfiguration" class="springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration" />

A configuração acima é responsável por habilitar o Swagger em nosso projeto para que o mesmo possa identificar nosso serviços e gerar a documentação.

Já na configuração mostrada abaixo, estamos configurando alguns recursos estáticos (HTML, CSS, JavaScritp) permitindo que o Swagger gera a documentação da API Rest em formato HTML para que a mesma possa ser visualizada no browser.

    <mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/"/>
    <mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>

Para finalizar, a última configuração necessária é declararmos o bean ApplicationSwaggerConfig como mostrado abaixo:

    <!-- Bean para alterar as informações gerais da API. -->
    <bean name="applicationSwaggerConfig" class="com.projeto.configuracao.ApplicationSwaggerConfig"/>

O código da classe ApplicationSwaggerConfig.java utilizado na configuração anterior é exibido na Listagem 3:

    public class ApplicationSwaggerConfig {
    	  @Bean
	  public springfox.documentation.spring.web.plugins.Docket docket() {
		Docket docket = new Docket(springfox.documentation.spi.DocumentationType.SWAGGER_2);
		return docket.apiInfo(apiInfo());
	  }

	  private ApiInfo apiInfo() {
		ApiInfo apiInfo = new ApiInfo(
                  "Cliente REST API",
                  "Exemplo de descrição da API.",
                  "Versão API 1.0",
                  "Termos de uso",
                  "contato@e-mail.com",
                  "API License",
                  "API License URL"
                );
		return apiInfo;
	   }
     }
Listagem 3: Classe com configurações adicionais do Swagger.

A classe ApplicationSwaggerConfig apresentada na Listagem 3, tem como objetivo realizar configurações gerais da documentação que será gerada pelo Swagger. Podemos observar no método apiInfo(), que estamos configurando o nome da API como “Cliente REST API”, uma breve descrição da API, bem como sua versão, termos de uso, e-mail de contato e informações de licença. Todos esses dados estarão presentes na documentação da API.

Neste ponto, encerramos toda a parte de configuração de nossa aplicação Spring para integrá-la com o Swagger. Vamos agora começar a gerar a documentação de nossa API Rest.
Como exemplo, utilizaremos um serviço construído utilizando Spring MVC e que roda em um servidor Tomcat versão 7. Na Listagem 4, temos um exemplo de API Rest de clientes.

@RestController
@RequestMapping("/v1")
public class ClienteController {
    @RequestMapping(value="/clientes", method = RequestMethod.GET)
    public ResponseEntity consultaClientes() {
        return ResponseEntity.status(HttpStatus.OK).body("Consulta de clientes executada com sucesso!");
    }
	
    @RequestMapping(value="/clientes/{clienteId}", method = RequestMethod.GET)
    public ResponseEntity consultaClientesPorId(@PathVariable Long clienteId) {
        return  ResponseEntity.status(HttpStatus.OK).body("Consulta executada com sucesso! Id=" + clienteId”);
    }
	
    @RequestMapping(value="/clientes", method = RequestMethod.POST)
    public ResponseEntity criaCliente(@RequestBody ClienteDTO clienteDTO) {
        return ResponseEntity.status(HttpStatus.CREATED).body("Inserido com sucesso!");
    }
}
Listagem 4: API Rest de Clientes.

A API Rest apresentada na Listagem 4, possui três recursos: Buscar todos os clientes, buscar um cliente pelo seu ID (identificador) e criar um cliente.

Para criar a documentação dessa API, vamos utilizar algumas anotações do Swagger, anotando a classe ClienteController e seus métodos de serviços. Por meio dessas anotações informaremos o nome da API, os nomes dos serviços e métodos HTTP, parâmetros de entrada, etc. Dessa forma, podemos deixar a classe ClienteController configurada como mostra a Listagem 5.

@Api(value="Clientes API")
@RestController
@RequestMapping("/v1")
public class ClienteController {

  @ApiOperation(value="Consulta todos clientes do sistema", notes="Consulta síncrona.")
  @RequestMapping(value="/clientes", method = RequestMethod.GET)
  public ResponseEntity consultaClientes() {
        return ResponseEntity.status(HttpStatus.OK).body("Consulta de clientes executada com sucesso!");
  }

  @ApiOperation(value="Consulta um cliente no sistema", notes="Consulta síncrona.")
  @RequestMapping(value="/clientes/{clienteId}", method = RequestMethod.GET)
  public ResponseEntity consultaClientesPorId(@ApiParam(value="Id do cliente")
                                                      @PathVariable Long clienteId) {

        return  ResponseEntity.status(HttpStatus.OK).body("Consulta executada com sucesso! Id=" + clienteId”);
  }

  @ApiOperation(value="Cria um novo cliente.", notes="Inserção síncrona.")
  @RequestMapping(value="/clientes", method = RequestMethod.POST)
  public ResponseEntity criarCliente(@RequestBody ClienteDTO clienteDTO) {
       return ResponseEntity.status(HttpStatus.CREATED).body("Inserido com sucesso!");
  }
}
Listagem 5: API Rest de Clientes com anotações do Swagger.

Como podemos observar as principais anotações do Swagger utilizadas foram:

@Api – Utilizada para anotar a classe que cria uma API Rest

@ApiOperation – Descreve uma operação ou um recurso HTTP

@ApiParam – Representa um parâmetro de entrada em uma operação/recurso HTTP

Um detalhe importante que devemos nos atentar é que no método criarCliente() da Listagem 5 recebemos como parâmetro um objeto ClienteDTO que possui informações de um cliente para que o mesmo seja criado. Na Listagem 6, temos o código dessa classe.

@ApiModel(value = "Cliente")
public class ClienteDTO {

   @ApiModelProperty(value = "Id do cliente.", required=true)
   private Long id;

   @ApiModelProperty(value = "Nome do cliente.")
   private String nome;

  /*Metodos getter e setter omitidos*/
}
Listagem 6: Classe ClienteDTO com anotações do Swagger.

Como podemos observar na Listagem 6, os objetos utilizados como entrada ou resposta dos serviços também podem receber as anotações do Swagger. Nesse exemplo utilizamos duas anotações:

@ApiModel – Usada para nomear a classe do modelo.

@ApiModelProperty – Usada para descrever uma propriedade dentro da classe modelo.

Com essas anotações, os atributos do objeto ClienteDTO farão parte da documentação da API gerada pelo Swagger.

Neste momento, podemos testar a aplicação e ver a documentação gerada pelo Swagger. Para isso, devemos compilar a aplicação e implantá-la no servidor Tomcat 7 e ver os resultados.
Com o servidor Tomcat iniciado podemos consultar a documentação por meio do seguinte padrão de URL: localhost:8080/minhaAplicacao/swagger-ui.html

Abaixo temos a imagem da documentação gerada:

API REST COM SWAGGER

Figura 1: Documentação da API REST de Clientes com Swagger.

Como vimos ao longo deste post é relativamente simples gerar uma documentação de uma API Rest já existente (Contract Last) por meio do Swagger. Por meio dessa sequência de passamos, todos os serviços da API estão devidamente documentados enriquecendo, assim, nossa API e, sobretudo facilitando a troca de informação entre os desenvolvedores e os clientes da API.

REFERÊNCIAS

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

Documentação de referência do Spring Fox.

http://swagger.io/

Site Oficial do Swagger

Por EDMAR BREGAGNOLI

Postado em: 18 de março de 2016

Confira outros artigos do nosso blog

[Webinar] Profile de aplicações Java com Oracle Mission Control e Flight Recorder

24 de julho de 2017

Danival Calegari

Criando Mocks de serviços REST com SoapUI

27 de junho de 2017

Monise Costa

Three laws that enable agile software development

09 de março de 2017

Celso Gonçalves Junior

Medindo performance de uma API REST

21 de fevereiro de 2017

Monise Costa

Deixe seu comentário