Spring

Como criar Web Services RESTful com Spring Boot

Você quer aprender como criar Web Services RESTful de forma simples e rápida?

No post 4 Conceitos sobre REST que Qualquer Desenvolvedor Precisa Conhecer, nós discutimos uma série de características que um sistema REST deve possuir, mas não demos um foco em web services, e nem mesmo demonstramos algum tipo de implementação.

Neste post, você vai aprender como dar os primeiros passos para criar APIs RESTful com o Spring Boot.

O que é Spring Boot?

O Spring Boot é um framework que tem como base o core de funcionalidades que já estamos familiarizados a utilizar com outros frameworks da família Spring, como injeção de dependências, gerenciamento de dados com JPA, segurança, dentre outros.

Uma das principais características desse framework é fornecer um nível maior de produtividade para desenvolvedores.

Por possuir características de modularidade, aplicações desenvolvidas com o Spring Boot podem fazer uso apenas das funcionalidades necessárias, o que diminui a complexidade de desenvolvimento e operação do sistema.

Com o Spring Boot, você pode gerar um único pacote JAR que contenha tudo o que você precisa, como por exemplo um servidor Web, gerenciador de dados, segurança e etc. Dessa maneira, o seu deploy fica muito mais simplificado.

Além disso, muitas configurações que antes precisavam ser feitas com extensos arquivos XML, agora são feitas de forma programática, e muitas vezes já veem disponibilizadas prontas pra uso.

A seguir nós vamos detalhar o desenvolvimento de um Web Service utilizando o Spring Boot como base, e você vai perceber o quão simples pode ser o desenvolvimento de uma aplicação que faz uso desse framework.

Criando um Web Service RESTful

O primeiro passo para a criação de nosso web service, é a criação de um projeto Maven. Caso você prefira, é possível também a utilização do Gradle, no site de referência do Spring Boot você consegue mais detalhes sobre a criação nesse formato.

Criando o seu projeto Maven a partir do Eclipse ou alguma outra IDE de sua preferência, você deve configurar o seu POM conforme o 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>com.algaworks</groupId> 
     <artifactId>postrest</artifactId> 
     <version>1.0.0-SNAPSHOT</version>
     <packaging>jar</packaging> 

     <parent> 
         <groupId>org.springframework.boot</groupId> 
         <artifactId>spring-boot-starter-parent</artifactId> 
         <version>1.3.2.RELEASE</version> 
     </parent> 

     <dependencies> 
         <dependency> 
              <groupId>org.springframework.boot</groupId> 
              <artifactId>spring-boot-starter-web</artifactId> 
         </dependency> 
     </dependencies> 
</project>

Nesse POM, indicamos que desejamos utilizar como referência o projeto do Spring Boot e também declaramos que vamos utilizar recursos para o desenvolvimento de uma aplicação Web.

A dependência spring-boot-starter-web já possui todos os requisitos necessários que nós vamos precisar. Além de possuir um servidor Web embutido (Tomcat), ela possui as dependências que nos permite a criação do nosso web service.

Após a configuração do POM, você deve criar uma classe semelhante ao código mostrado abaixo. Essa classe é responsável pela execução da nossa aplicação.

package com.algaworks;

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

@SpringBootApplication
public class Main {

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

}

Caso o Spring Boot ainda não seja muito familiar e você esteja acostumado a empacotar aplicações Web em formatos WAR, você certamente deve estar se perguntando qual o motivo para criarmos esse método main, não é mesmo?

Lembra que eu falei que as dependências necessárias são embutidas dentro da própria aplicação? Dessa forma, o método main é o gatilho que será responsável por iniciar a nossa aplicação.

Não sei se você percebeu quando escrevemos o arquivo pom.xml, mas o formato gerado pela compilação do Maven é um JAR, dessa maneira, o main será o método a ser invocado na execução do nosso JAR.

Feito essa configuração e codificação inicial, o seu projeto já está pronto para evoluir. Caso queira testar e verificar se tudo está funcionando, você pode executar o método main, e irá perceber que o Spring Boot inicializará a aplicação pra você.

Como ainda não criamos nada que possa ser de fato acessado, não temos muitas coisas ainda a testar. E para dar continuidade, vamos prosseguir com a criação do nosso Web Service.

A ideia é criamos um Web Service que nos permita a busca e remoção de um recurso (caso o conceito “recurso” esteja um pouco vago, recomendo você ler o meu outro post que detalha este conceito), que eu denominei “Curso”.

A primeira coisa a ser feita, é a criação da classe Curso. Essa classe possui os atributos que vamos utilizar para representar o nosso conceito.

É uma classe simples, basicamente um POJO, mas que nos ajuda a compreender de forma simples como representar um recurso.

package com.algaworks.model;

public class Curso {

  private Integer id;
  private String nome;
  private String duracao;
  
  public Curso(Integer id, String nome, String duracao) {
    this.id = id;
    this.nome = nome;
    this.duracao = duracao;
  }
  
  // getters e setters omitidos

}

Após a criação da representação do nosso recurso Curso, já estamos prontos para criar a classe que será de fato o nosso recurso.

Perceba que a classe Curso que criamos é apenas uma representação, ou seja, são os dados que queremos retornar ao cliente.

O recurso de fato é criado a partir da criação de um controlador, que é responsável por receber e tratar as requisições vindas dos nossos clientes.

package com.algaworks.resource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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 com.algaworks.model.Curso;

@RestController
public class CursoResource {

  private Map<Integer, Curso> cursos;

  public CursoResource() {
    cursos = new HashMap<Integer, Curso>();

    Curso c1 = new Curso(1, "Workshop Rest", "24hs");
    Curso c2 = new Curso(2, "Workshop Spring MVC", "24hs");
    Curso c3 = new Curso(3, "Desenvolvimento Web com JSF 2", "60hs");

    cursos.put(1, c1);
    cursos.put(2, c2);
    cursos.put(3, c3);
  }

  @RequestMapping(value = "/cursos", method = RequestMethod.GET)
  public ResponseEntity<List<Curso>> listar() {
    return new ResponseEntity<List<Curso>>(new ArrayList<Curso>(cursos.values()), HttpStatus.OK);
  }

}

A anotação @RestController nos permite criar um controlador com características REST e que possa manipular as requisições vindas dos nossos clientes. Se você já está habituado a utilizar o Spring MVC, essa anotação é muito semelhante a @Controller.

Para simplificar o nosso exemplo, os dados que manipulamos foram colocados em um HashMap que foi inicializado no próprio construtor da classe CursoResource.

Outra coisa importante para discutirmos é o método listar. Perceba que o mesmo possui uma anotação @RequestMapping. Essa anotação é a responsável por fazer o mapeamento de nossa URI.

Nessa anotação, estamos determinando que a URI /cursos, a partir do método GET, poderá listar todos os cursos presentes no nosso HashMap.

Além disso, perceba que na linha onde fazemos o retorno dos nossos dados, foi adicionado um HttpStatus.OK. Essa opção indica que o Spring, ao montar nossa resposta, deve enviar um “200 OK” para o nosso cliente.

Ao acessar http://localhost:8080/cursos, você receberá uma resposta conforme a listagem abaixo:

[
  {
    "id": 1,
    "nome": "Workshop Rest",
    "duracao": "24hs"
  },
  {
    "id": 2,
    "nome": "Workshop Spring MVC",
    "duracao": "24hs"
  },
  {
    "id": 3,
    "nome": "Desenvolvimento Web com JSF 2",
    "duracao": "60hs"
  }
]

Outro recurso interessante que o Spring nos provê é o mapeamento de uma parte da URI como fonte de entrada para o nosso método. A implementação abaixo busca um curso a partir de um identificador.

@RequestMapping(value = "/cursos/{id}", method = RequestMethod.GET)
public ResponseEntity<Curso> buscar(@PathVariable("id") Integer id) {
  Curso curso = cursos.get(id);

  if (curso == null) {
    return new ResponseEntity<>(HttpStatus.NOT_FOUND);
  }

  return new ResponseEntity<Curso>(curso, HttpStatus.OK);
}

Perceba que mapeamos a nossa URI com o valor /cursos/{id} e que no parâmetro do nosso método buscar adicionamos uma anotação @PathVariable. Essa anotação nos permite fazer o bind do valor fornecido na URI com o parâmetro do nosso método.

É importante notarmos também o tratamento de cursos não encontrados. Perceba que se o ID do curso fornecido na URL não for encontrado no nosso HashMap, uma resposta NOT_FOUND é retornada. Ou seja, o usuário irá receber uma resposta HTTP 404.

Essa tratativa é importante e faz com que o nosso Web Service siga os padrões propostos pelo protocolo HTTP.

Até aqui, nossos métodos sempre trataram requisições GET. Caso seja necessário a tratativa de outras funcionalidades, vamos precisar indicar ao Spring que nosso método aceita outra opção que não seja o GET.

Podemos ver um exemplo com o método DELETE. Esse código nos apresenta um exemplo no qual podemos remover um determinado recurso.

@RequestMapping(value = "/cursos/{id}", method = RequestMethod.DELETE)
public ResponseEntity<?> deletar(@PathVariable("id") int id) {
  Curso curso = cursos.remove(id);

  if (curso == null) {
    return new ResponseEntity<>(HttpStatus.NOT_FOUND);
  }

  return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}

Perceba que fizemos a tratativa caso o recurso não seja encontrado da mesma forma que fizemos na implementação da busca. Além disso, veja que ao invés do código “200 OK”, estamos retornando um “NO_CONTENT”.

Essa é a resposta normalmente utilizada quando executamos a remoção de um recurso. Esse código irá retornar uma resposta “204 NO CONTENT” para o cliente do nosso Web Service.

(Nota: Quer entrar um pouco mais a fundo nos conceitos de WebServices REST com Java? Baixe nosso livreto gratuito!)

Livreto Gratuito de REST com Java

Conclusão

Neste post, discutimos sobre algumas características do framework Spring Boot e como ele pode nos ajudar na criação de um Web Service RESTful.

Criamos um serviço bem simples, mas que nos ajuda a compreender de forma rápida como podemos criar Web Services.

Em artigos futuros, vamos continuar discutindo sobre a criação de Web Services RESTful e entender algumas outras funcionalidades que podemos adicionar para criarmos aplicações cada vez melhores.

Deixe seu comentário aí abaixo dizendo o que achou desse artigo e também com sugestões. ;)

Obrigado e até a próxima!

Formado em Ciência da Computação, Especialista em Segurança da Informação e detentor das certificações SCJP e LPIC-1. Palestrante de fóruns internacionais de Software Livre e congressos de Engenharia de Software. Atua também como Professor nos cursos de Ciência da Computação e Sistemas de Informação da Unitri em Uberlândia.

Olá,

o que você achou deste conteúdo? Conte nos comentários.

Junte-se a mais de 100.000 pessoas

Entre para nossa lista e receba conteúdos exclusivos e com prioridade

Você se Inscreveu com Sucesso!