Introdução
Com o crescimento exponencial de aplicações complexas, a arquitetura de microserviços se tornou uma abordagem popular para o desenvolvimento de software. Este tutorial oferece um guia passo a passo sobre como desenvolver aplicações de microserviços utilizando Janus Gateway, Spring Boot e Docker. Vamos explorar como estruturar sua aplicação, gerenciar o tráfego de serviços, e garantir que cada componente funcione de maneira otimizada e integrada. O uso do Janus como gateway de API permite uma gestão eficiente das requisições e respostas, ao mesmo tempo que oferece funcionalidades avançadas como load balancing. Neste guia, você irá aprender a implementar tudo isso em um ambiente de desenvolvimento adequado, com a capacidade de escalar sua aplicação conforme necessário.
Etapas
Configuração do Ambiente de Desenvolvimento
Comece instalando o Java JDK e o Maven em sua máquina se ainda não estiverem instalados. Além disso, você precisará ter o Docker instalado para contêinerizar a sua aplicação posteriormente. Verifique as versões instaladas usando os comandos `java -version`, `mvn -version` e `docker –version`. Caso não tenha instalado, siga as instruções do site oficial para cada uma dessas ferramentas.
commands# Verificar versões instaladas
java -version
mvn -version
docker --versionCriação do Projeto Spring Boot
Utilize o Spring Initializr para gerar um novo projeto Spring Boot com as dependências necessárias. Configure o projeto com as seguintes opções: **Project**: Maven, **Language**: Java, **Spring Boot**: última versão estável, **Packaging**: Jar, **Java**: 11 ou superior. Adicione as dependências ‘Spring Web’, ‘Spring Boot DevTools’, ‘Spring Data JPA’ e ‘H2 Database’. Baixe e descompacte o projeto em sua máquina.
pom.xml<?xml version="1.0" encoding="UTF-8"?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>microservices-janus</artifactId> <version>0.0.1-SNAPSHOT</version> <name>microservices-janus</name> <description>Aplicações de Microserviços com Janus e Spring Boot</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Configuração do Banco de Dados H2
Edite o arquivo `application.properties` para definir as propriedades do banco de dados H2, permitindo que a aplicação armazene dados em memória e habilite o console web para visualização.
application.propertiesspring.h2.console.enabled=true spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.hibernate.ddl-auto=update
Criação da Entidade `Servico`
Implemente a classe modelo `Servico` que representará os microserviços na aplicação. Use anotações JPA para mapear a classe à tabela do banco de dados.
Servico.javapackage com.example.microservicesjanus.model; import javax.persistence.*; @Entity @Table(name = "servicos") public class Servico { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String nome; @Column(nullable = false) private String descricao; // Getters e Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getDescricao() { return descricao; } public void setDescricao(String descricao) { this.descricao = descricao; } }
Criação do Repositório `ServicoRepository`
Implemente a interface `ServicoRepository`, que estende `JpaRepository` e fornece métodos CRUD para manipulação da entidade Servico.
ServicoRepository.javapackage com.example.microservicesjanus.repository; import com.example.microservicesjanus.model.Servico; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface ServicoRepository extends JpaRepository<Servico, Long> { // Métodos personalizados podem ser definidos aqui }
Implementação do Serviço `ServicoService`
Crie a classe `ServicoService`, que contém a lógica de negócios e utiliza o `ServicoRepository` para interagir com o banco de dados de microserviços.
ServicoService.javapackage com.example.microservicesjanus.service; import com.example.microservicesjanus.model.Servico; import com.example.microservicesjanus.repository.ServicoRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class ServicoService { @Autowired private ServicoRepository servicoRepository; public List<Servico> findAll() { return servicoRepository.findAll(); } public Optional<Servico> findById(Long id) { return servicoRepository.findById(id); } public Servico save(Servico servico) { return servicoRepository.save(servico); } public Servico update(Long id, Servico servicoDetails) { Servico servico = servicoRepository.findById(id).orElseThrow(() -> new RuntimeException("Servico não encontrado")); servico.setNome(servicoDetails.getNome()); servico.setDescricao(servicoDetails.getDescricao()); return servicoRepository.save(servico); } public void deleteById(Long id) { servicoRepository.deleteById(id); } }
Implementação do Controlador `ServicoController`
Crie a classe `ServicoController` para expor os endpoints da API, permitindo operações CRUD em microserviços.
ServicoController.javapackage com.example.microservicesjanus.controller; import com.example.microservicesjanus.model.Servico; import com.example.microservicesjanus.service.ServicoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/servicos") public class ServicoController { @Autowired private ServicoService servicoService; @GetMapping public List<Servico> getAllServicos() { return servicoService.findAll(); } @GetMapping("/{id}") public ResponseEntity<Servico> getServicoById(@PathVariable Long id) { return servicoService.findById(id) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } @PostMapping public Servico createServico(@RequestBody Servico servico) { return servicoService.save(servico); } @PutMapping("/{id}") public ResponseEntity<Servico> updateServico(@PathVariable Long id, @RequestBody Servico servicoDetails) { return ResponseEntity.ok(servicoService.update(id, servicoDetails)); } @DeleteMapping("/{id}") public ResponseEntity<Void> deleteServico(@PathVariable Long id) { servicoService.deleteById(id); return ResponseEntity.noContent().build(); } }
Implementação de Testes Unitários
Crie a classe de testes `ServicoServiceTest` para validar a lógica de negócios e operações CRUD da aplicação de microserviços.
ServicoServiceTest.javapackage com.example.microservicesjanus.service; import com.example.microservicesjanus.model.Servico; import com.example.microservicesjanus.repository.ServicoRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; public class ServicoServiceTest { @InjectMocks private ServicoService servicoService; @Mock private ServicoRepository servicoRepository; @BeforeEach public void init() { MockitoAnnotations.openMocks(this); } @Test public void testFindAll() { Servico servico1 = new Servico(); servico1.setId(1L); servico1.setNome("Servico 1"); servico1.setDescricao("Descricao 1"); Servico servico2 = new Servico(); servico2.setId(2L); servico2.setNome("Servico 2"); servico2.setDescricao("Descricao 2"); when(servicoRepository.findAll()).thenReturn(Arrays.asList(servico1, servico2)); List<Servico> servicos = servicoService.findAll(); assertEquals(2, servicos.size()); verify(servicoRepository, times(1)).findAll(); } // Testes adicionais para os métodos findById, save, update e deleteById }
Executando a Aplicação e Testes
Utilize o Maven para compilar e executar a aplicação. Execute os testes unitários para garantir que todos os componentes funcionem como esperado. Utilize ferramentas como Postman ou cURL para testar os endpoints da API.
commands# Compilar e executar a aplicação
mvn spring-boot:run
# Executar os testes unitários
mvn testcurl_examples# Listar todos os serviços
curl -X GET http://localhost:8080/api/servicos
# Criar um novo serviço
curl -X POST -H "Content-Type: application/json" -d '{"nome":"Novo Serviço", "descricao":"Descrição do Novo Serviço"}' http://localhost:8080/api/servicos
Conclusão
Neste tutorial, você aprendeu como desenvolver aplicações de microserviços usando Janus Gateway, Spring Boot e Docker. Cobriu desde a configuração inicial do ambiente de desenvolvimento, passando pela criação de entidades JPA e exposições de APIs, até a implementação de testes unitários para garantir a qualidade da aplicação. Com esse conhecimento, você está preparado para levar suas habilidades de desenvolvimento de software a um nível mais elevado, explorando mais sobre microserviços e arquiteturas escaláveis, promovendo o crescimento e robustez de suas aplicações.