Arquivo por categoria Swagger

Aplicações RESTful HATEOAS com SpringBoot


O HATEOAS, é uma das principais constraints arquiteturais do REST e possibilita a navegação entre recursos, que são representações dos modelos de negócio da aplicação. Esse post é bem mão na massa e se quiser aprofundar um pouco mais em conceitos teóricos de HATEOAS confira o nosso post Entendendo HATEOAS. Vamos tomar como base a aplicação desenvolvida no nosso outro post Documentando aplicações REST com SpringBoot e Swagger. Para começar você pode baixar o código deste post aqui e descompactar o arquivo zip e importar na sua IDE preferida ou clonar usando Git:


git clone https://github.com/leandrocgsi/simple-rest-example-swagger.git


Primeiro altere o pom.xml adicionando os trechos destacados por comentários abaixo.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>br.com.erudio</groupId>
    <artifactId>simple-rest-example-hateoas</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
    </parent>
    
    <dependencies>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        
        <!-- Adicione a dependencia de HATEOAS-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>
        
        <dependency>
            <groupId>com.mangofactory</groupId>
            <artifactId>swagger-springmvc</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.ajar</groupId>
            <artifactId>swagger-spring-mvc-ui</artifactId>
            <version>0.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        
        <!-- Adicione as dependencias de teste -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>        
        
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
        <repository>
            <id>jcenter-release</id>
            <name>jcenter</name>
            <url>http://oss.jfrog.org/artifactory/oss-release-local/</url>
        </repository>
    </repositories>
    
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
    
</project>


Primeiro vamos alterar a classe Greeting que agora ira extender ResourceSupport.


package br.com.erudio.models;

import org.springframework.hateoas.ResourceSupport;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Greeting extends ResourceSupport {

    private final long idGreeting;
    private final String content;

    @JsonCreator
    public Greeting(@JsonProperty("id") long id, @JsonProperty("content") String content) {
        this.idGreeting = id;
        this.content = content;
    }

    public long getIdGreeting() {
        return idGreeting;
    }

    public String getContent() {
        return content;
    }
}


Agora adicione os trechos comentados a classe GreetingController.


package br.com.erudio.web.controllers;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Greeting;

@Api(value = "greeting")
@RestController
@RequestMapping("/greeting")
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

	@ApiOperation(value = "Show Greeting Message" )
	@ResponseStatus(HttpStatus.OK)
    @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public HttpEntity<Greeting> greeting(@RequestParam(value="name", defaultValue="World") String name) {
		Greeting greeting = new Greeting(counter.incrementAndGet(), String.format(template, name));
		
		// Na prática essa linha adiciona uma auto referência ao próprio endpoint
		// e apenas esse pequeno trecho de código já é o suficiente para que o endpoint 
		// greeting seja HATEOAS
		greeting.add(linkTo(methodOn(GreetingController.class).greeting(name)).withSelfRel());
        
		return new ResponseEntity<Greeting>(greeting, HttpStatus.OK);
    }
}


Se você iniciar a aplicação e acessar o endereço localhost:8080/greeting verá algo similar a imagem abaixo.

postagem_4_0


package br.com.erudio.models;

import java.io.Serializable;

import org.springframework.hateoas.ResourceSupport;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

// Adicione a anotação @JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)

//Extenda ResourceSupport
public class Person extends ResourceSupport implements Serializable{
    
    private static final long serialVersionUID = 1L;
    
	// Por padrão implementação HATEOAS do Spring tem um atributo id
	// como default por isso o ID de nossa entidade deve ser alterado
    private Long idPerson;
    private String firstName;
    private String lastName;
    private String address;
    
    public Person() {}

	public Long getIdPerson() {
        return idPerson;
    }
    
    public void setIdPerson(Long id) {
        this.idPerson = id;
    }
    
    public String getFirstName() {
        return firstName;
    }
    
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    
    public String getLastName() {
        return lastName;
    }
    
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    
    public String getAddress() {
        return address;
    }
    
    public void setAddress(String address) {
        this.address = address;
    }
}


Agora vamos alterar a classe PersonController:


package br.com.erudio.web.controllers;
 
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
 
import java.util.ArrayList;
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
 
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
 
import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;
 
@Api(value = "person")
@RestController
@RequestMapping("/person/")
public class PersonController {
     
    @Autowired
    private PersonService personService;
	@ApiOperation(value = "Find person by ID" )
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{personId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public Person get(@PathVariable(value = "personId") String personId){
        Person person = personService.findById(personId);
		
		//Adicione uma auto referencia ao método get do controller passando o ID como parâmetro
        person.add(linkTo(methodOn(PersonController.class).get(personId)).withSelfRel());
		return person;
    }
     
    .
    .
    .
     
}


Note que ao acessar esse recurso com uma ferramenta como o POSTman teremos uma resultado similar a imagem abaixo.


postagem_4_1


Agora vamos alterar o findAll:


package br.com.erudio.web.controllers;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;

@Api(value = "person")
@RestController
@RequestMapping("/person/")
public class PersonController {
	
	@Autowired
	private PersonService personService;
	
	.
	.
	.
	
	@ApiOperation(value = "Find all persons" )
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(value = "/findAll", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	public List<Person> findAll(){
		List<Person> persons = personService.findAll();
		ArrayList<Person> personsReturn = new ArrayList<Person>();
		for (Person person : persons) {
			String idPerson = person.getIdPerson().toString();
			
			// Adicione uma referencia ao método get do controller passando o ID como parâmetro
			// isso é feito para todos os elementos da lista
			person.add(linkTo(methodOn(PersonController.class).get(idPerson)).withSelfRel());
			personsReturn.add(person);
		}
		return personsReturn;
	}
	
	.
	.
	.
	
}


A imagem abaixo nos mostra o resultado dessa mudança. A nossa lista nos tras referencias únicas para cada um dos recursos.


postagem_4_2


Agora vamos adicionar o suporte a HATEOAS ao verbo POST da nossa aplicação.


package br.com.erudio.web.controllers;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;

@Api(value = "person")
@RestController
@RequestMapping("/person/")
public class PersonController {
	
	@Autowired
	private PersonService personService;
	
	.
	.
	.
	
	@ApiOperation(value = "Create a new person" )
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public Person create(@RequestBody Person person){
		Person createdPerson = personService.create(person);
		String idPerson = createdPerson.getIdPerson().toString();
		
		// Após criarmos um novo recurso do tipo Person nós recuperamos seu ID e adicionamos
		// uma referencia ao método get do controller passando o ID como parâmetro		
		createdPerson.add(linkTo(methodOn(PersonController.class).get(idPerson)).withSelfRel());
		return createdPerson;
	}
	
	.
	.
	.
	
}


Como se pode ver na imagem após salvar uma nova pessoa a aplicação retorna um link para que as informações da mesma possam ser acessadas.


postagem_4_3


Agora vamos modificar o verbo PUT.


package br.com.erudio.web.controllers;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;

@Api(value = "person")
@RestController
@RequestMapping("/person/")
public class PersonController {
	
	@Autowired
	private PersonService personService;
		
	.
	.
	.
	
	@ApiOperation(value = "Update an existing person")
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(method = RequestMethod.PUT,consumes = MediaType.APPLICATION_JSON_VALUE)
	public Person update(@RequestBody Person person){
		Person updatedPerson = personService.update(person);
		String idPerson = updatedPerson.getIdPerson().toString();
		
		// Após atualizarmos um recurso nós recuperamos seu ID e adicionamos
		// uma referencia ao método get do controller passando o ID como parâmetro		
		updatedPerson.add(linkTo(methodOn(PersonController.class).get(idPerson)).withSelfRel());		
		return updatedPerson;
	}
	
	.
	.
	.
	
}


Da mesma forma que com o verbo POST após atualizar uma pessoa a aplicação retorna um link para que as informações da mesma possam ser acessadas.


postagem_4_4


Como o verbo DELETE exclui um recurso não há necessidade de adicionar suporte a HATEOAS nele. Sendo assim fechamos a nossa implementação e podemos dizer que a nossa API é finalmente RESTful. Assim como nos posts anteriores você pode baixar o código deste post aqui e descompactar o arquivo zip e importar na sua IDE preferida ou clonar usando Git:

git clone https://github.com/leandrocgsi/simple-rest-example-hateoas.git


É isso aí bons estudos e continuem ligados no blog para mais novidades 😉


Tags: , , , , ,

Documentando aplicações REST com SpringBoot e Swagger



O Swagger é um dos frameworks mais usados para se documentar API’s REST. Ele facilita para que os clientes que consomem nossas API’s saibam quais os parâmetros nossas operações recebem, qual o retorno, o modelo, o media type retornado JSON, XML, CSV, binário etc. Sendo assim os clientes não precisam necessariamente discutir com a equipe de desenvolvimento da API sobre como usá-la. Pode-se dizer que a grosso modo o Swagger se comporta como o velho WSDL das aplicações SOAP. Sendo assim esse framework valoriza e muito nossas aplicações.


Tomando como base o projeto do post anterior vamos adicionar as configurações necessárias para habilitar o Swagger na aplicação. Para isso abra o arquivo pom.xml e adicione as tags destacadas com comentários no código abaixo.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	
	<groupId>br.com.erudio</groupId>
	<artifactId>simple-rest-example-swagger</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
    </parent>
    
    <dependencies>
    	
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
    	<!-- Adicionando a dependencia do Spring Boot Starter Actuator -->
    	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		
		<!-- Adicione as dependências do Swagger API necessárias para gerar a documentação da aplicação-->
		<dependency>
			<groupId>com.mangofactory</groupId>
			<artifactId>swagger-springmvc</artifactId>
			<version>1.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.ajar</groupId>
			<artifactId>swagger-spring-mvc-ui</artifactId>
			<version>0.4</version>
		</dependency>
		<dependency>
    		<groupId>org.apache.tomcat.embed</groupId>
    		<artifactId>tomcat-embed-jasper</artifactId>
    		<scope>provided</scope>
		</dependency>
		
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
   		
   		<!-- Adicione o repositório do Swagger ao projeto-->
		<repository>
			<id>jcenter-release</id>
			<name>jcenter</name>
			<url>http://oss.jfrog.org/artifactory/oss-release-local/</url>
		</repository>
    </repositories>
    
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
	
</project>



Feito isto precisamos alterar a classe Application para que ela acione o Swagger quando inicializar a aplicação.


package br.com.erudio;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.mangofactory.swagger.configuration.SpringSwaggerConfig;
import com.mangofactory.swagger.models.dto.ApiInfo;
import com.mangofactory.swagger.plugin.EnableSwagger;
import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin;

@Configuration // Define a classe como classe de configuração
@EnableAutoConfiguration // Habilita a autoconfiguração
@EnableSwagger //Habilita o Swagger
@ComponentScan(basePackages = {"br.com.erudio"}) //Escaneia todos os pacotes com o padrão br.com.erudio
public class Application {
    
	//Injeta uma instancia de SpringSwaggerConfig
    @Autowired
    private SpringSwaggerConfig swaggerConfig;
    
    public static void main(String[] args) {
		   //Troque esta linha SpringApplication.run(Application.class, args); pela linha abaixo
           new SpringApplicationBuilder(Application.class).web(true).run(args);
    }
    
    @Bean
    public SwaggerSpringMvcPlugin groupOnePlugin() {
       return new SwaggerSpringMvcPlugin(swaggerConfig)
			//Adiciona as configurações do Swagger ao SwaggerSpringMvcPlugin 
           .apiInfo(apiInfo()) //Adiciona as propriedades de configuração
           .includePatterns("/person.*?", "/greeting.*?") //Habilita o Swagger para os nossos 2 endpoints
           .swaggerGroup("admin");
    }
    
    private ApiInfo apiInfo() {
       ApiInfo apiInfo = new ApiInfo( //Configurações de contato, licença etc não nescessáriamente precisa ser definida
             "Swagger With Spring Boot",
             "This is a simple application to demonstrate how to work with Swagger in Spring Boot project!",
             "Free to use and mess around",
             "erudio@gmail.com",
             "Open Licence",
             "myemail@gmail.com"
       );
       return apiInfo;
    }
}



Agora que o Swagger já está configurado vamos documentar o endpoint Greeting.


package br.com.erudio.web.controllers;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Greeting;

@Api(value = "greeting") //Diz ao Swagger que esse é um endpoint e REST deve ser documentado
@RestController
@RequestMapping("/greeting")
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

	@ApiOperation(value = "Show Greeting Message" )
	 //Diz ao Swagger que essa operação REST deve ser documentado
	@ResponseStatus(HttpStatus.OK)
    @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
}



Como se pode ver é extremamente simples documentar a nossa API agora vamos vazer o mesmo com o endpoint Person.


package br.com.erudio.web.controllers;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;


@Api(value = "person") //Diz ao Swagger que esse é um endpoint e REST deve ser documentado
@RestController
@RequestMapping("/person/")
public class PersonController {
	
	@Autowired
	private PersonService personService;
	
	@ApiOperation(value = "Find person by ID" )
	//Diz ao Swagger que essa operação REST deve ser documentado
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{personId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public Person get(@PathVariable(value = "personId") String personId){
        return personService.findById(personId);
    }
	
	@ApiOperation(value = "Find all persons" )
	//Diz ao Swagger que essa operação REST deve ser documentado
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(value = "/findAll", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	public List<Person> findAll(){
		return personService.findAll();
	}
	
	@ApiOperation(value = "Create a new person" )
	//Diz ao Swagger que essa operação REST deve ser documentado
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public Person create(@RequestBody Person person){
		return personService.create(person);
	}
	
	@ApiOperation(value = "Update an existing person")
	//Diz ao Swagger que essa operação REST deve ser documentado
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE)
	public Person update(@RequestBody Person person){
		return personService.update(person);
	}

	@ApiOperation(value = "Delete person by ID" )
	//Diz ao Swagger que essa operação REST deve ser documentado
	@ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{personId}", method = RequestMethod.DELETE)
    public void delete(@PathVariable(value = "personId") String personId){
        personService.delete(personId);
    }	
}



Não parece mas já terminamos toda a codificação necessária por adicionar o Swagger à nossa API mais uma vez acesse a classe Application e inicie a aplicação como no post anterior. Após inicializada a aplicação acesse a URL:


	localhost:8080/sdoc.jsp



Essa é a URL padrão da documentação e nunca tentei alterá-la. Ao acessá-la você verá algo similar a imagem abaixo documentando cada uma das operações dos nossos endpoints. Bastando clicar sobre cada uma para expandir e ver todos os detalhes da mesma.



postagem_3_1



Na imagem abaixo podemos ver a documentação da operação findAll. Temos a definição do modelo que ela nos retorna, o tipo de dados que ela retorna no caso JSON, os StatusCode que ela pode retornar, se clicarmos em Try Out o Swagger nos permite testar nossas operações. Ao executarmos esse teste a nossa API nos retornou um array de pessoas, o cabeçalho e o StatusCode 200 OK.



postagem_3_5


Chegamos com este post ao final da série de posts, práticos, sobre serviços REST. Você pode baixar o código deste post aqui e descompactar o arquivo zip e importar na sua IDE preferida ou clonar usando Git:

git clone https://github.com/leandrocgsi/simple-rest-example-swagger.git



Agora você já consegue dar os primeiros passos na criação de serviços REST, conhece conceitos, teóricos e práticos, básicos para executar esse tipo de tarefa. Sendo assim continue ligado no blog, por que no próximos posts iremos detonar o Rock’n Roll com outras tecnologias. É isso aí bons estudos.

Tags: , , , , ,