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!

Blog da AlgaWorks
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.