Introdução
Neste tutorial, vamos explorar como integrar o Genie Framework em projetos de microserviços, utilizando o Spring Boot para a construção de APIs escaláveis e eficientes. Com o suporte de ferramentas como Docker e Kubernetes, vamos aprender a otimizar o desenvolvimento ágil, garantindo que suas aplicações possam ser facilmente implantadas, geridas e escaladas. O Genie Framework permite que desenvolvedores abstraiam tarefas repetitivas, promovendo a automação e facilitando a criação de aplicativos robustos. Através de exemplos práticos, iremos configurar um ambiente de desenvolvimento que utiliza essas tecnologias em conjunto, cobrindo desde a criação do projeto até a implementação e testes unitários, tornando o processo fluido e produtivo.
Etapas
Configuração do Ambiente de Desenvolvimento
Certifique-se de ter o JDK (Java Development Kit) e o Maven instalados em sua máquina. Verifique as versões instaladas usando os comandos `java -version` e `mvn -version`. Também vamos instalar o Docker e o Kubernetes se ainda não estiverem instalados.
commands# Verificar versões instaladas
java -version
mvn -version
# Verificar versões do Docker e Kubernetes
docker --version
kubectl version --clientCriação do Projeto Spring Boot
Utilize o Spring Initializr para gerar um novo projeto Spring Boot. 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 Data JPA’ e ‘H2 Database’. Baixe e descompacte o projeto em seu ambiente de trabalho.
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>api-genie-integration</artifactId> <version>0.0.1-SNAPSHOT</version> <name>api-genie-integration</name> <description>API com integração ao Genie Framework</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 e habilitar o console web para visualizar os dados.
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 `Produto`
Implemente a classe modelo `Produto`, representando os produtos na aplicação. Use anotações JPA para mapear a classe à tabela do banco de dados.
Produto.javapackage com.example.apigenieintegration.model; import javax.persistence.*; @Entity @Table(name = "produtos") public class Produto { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String nome; @Column(nullable = false) private Double preco; // 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 Double getPreco() { return preco; } public void setPreco(Double preco) { this.preco = preco; } }
Criação do Repositório `ProdutoRepository`
Implemente a interface `ProdutoRepository`, que estende `JpaRepository` e fornece métodos CRUD.
ProdutoRepository.javapackage com.example.apigenieintegration.repository; import com.example.apigenieintegration.model.Produto; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface ProdutoRepository extends JpaRepository<Produto, Long> { // Métodos personalizados podem ser definidos aqui }
Implementação do Serviço `ProdutoService`
Crie a classe `ProdutoService`, que contém a lógica de negócios e utiliza o `ProdutoRepository` para interagir com o banco de dados.
ProdutoService.javapackage com.example.apigenieintegration.service; import com.example.apigenieintegration.model.Produto; import com.example.apigenieintegration.repository.ProdutoRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class ProdutoService { @Autowired private ProdutoRepository produtoRepository; public List<Produto> findAll() { return produtoRepository.findAll(); } public Optional<Produto> findById(Long id) { return produtoRepository.findById(id); } public Produto save(Produto produto) { return produtoRepository.save(produto); } public Produto update(Long id, Produto produtoDetails) { Produto produto = produtoRepository.findById(id).orElseThrow(() -> new RuntimeException("Produto não encontrado")); produto.setNome(produtoDetails.getNome()); produto.setPreco(produtoDetails.getPreco()); return produtoRepository.save(produto); } public void deleteById(Long id) { produtoRepository.deleteById(id); } }
Implementação do Controlador `ProdutoController`
Crie a classe `ProdutoController` para expor os endpoints da API, permitindo operações CRUD.
ProdutoController.javapackage com.example.apigenieintegration.controller; import com.example.apigenieintegration.model.Produto; import com.example.apigenieintegration.service.ProdutoService; 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/produtos") public class ProdutoController { @Autowired private ProdutoService produtoService; @GetMapping public List<Produto> getAllProdutos() { return produtoService.findAll(); } @GetMapping("/{id}") public ResponseEntity<Produto> getProdutoById(@PathVariable Long id) { return produtoService.findById(id) .map(ResponseEntity::ok) .orElse(ResponseEntity.notFound().build()); } @PostMapping public Produto createProduto(@RequestBody Produto produto) { return produtoService.save(produto); } @PutMapping("/{id}") public ResponseEntity<Produto> updateProduto(@PathVariable Long id, @RequestBody Produto produtoDetails) { return ResponseEntity.ok(produtoService.update(id, produtoDetails)); } @DeleteMapping("/{id}") public ResponseEntity<Void> deleteProduto(@PathVariable Long id) { produtoService.deleteById(id); return ResponseEntity.noContent().build(); } }
Implementação de Testes Unitários
Crie a classe de testes `ProdutoServiceTest` para validar a lógica de negócios e operações CRUD da aplicação.
ProdutoServiceTest.javapackage com.example.apigenieintegration.service; import com.example.apigenieintegration.model.Produto; import com.example.apigenieintegration.repository.ProdutoRepository; 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 ProdutoServiceTest { @InjectMocks private ProdutoService produtoService; @Mock private ProdutoRepository produtoRepository; @BeforeEach public void init() { MockitoAnnotations.openMocks(this); } @Test public void testFindAll() { Produto produto1 = new Produto(); produto1.setId(1L); produto1.setNome("Produto 1"); produto1.setPreco(10.0); Produto produto2 = new Produto(); produto2.setId(2L); produto2.setNome("Produto 2"); produto2.setPreco(20.0); when(produtoRepository.findAll()).thenReturn(Arrays.asList(produto1, produto2)); List<Produto> produtos = produtoService.findAll(); assertEquals(2, produtos.size()); verify(produtoRepository, times(1)).findAll(); } // Testes adicionais para os métodos findById, save, update e deleteById }
Executando a Aplicação e Testes
Use o Maven para compilar e executar a aplicação. Em seguida, 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 produtos
curl -X GET http://localhost:8080/api/produtos
# Criar um novo produto
curl -X POST -H "Content-Type: application/json" -d '{"nome":"Novo Produto", "preco":99.99}' http://localhost:8080/api/produtosDockerização da Aplicação
Crie um Dockerfile para a aplicação e construa a imagem. Em seguida, execute a aplicação em um contêiner Docker.
DockerfileFROM openjdk:11-jre-slim COPY target/api-genie-integration-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
Implantação com Kubernetes
Crie um arquivo de manifesto Kubernetes para implantar sua aplicação em um cluster Kubernetes. Execute os comandos para aplicar a configuração.
k8s-deployment.yamlapiVersion: apps/v1 kind: Deployment metadata: name: api-genie spec: replicas: 1 selector: matchLabels: app: api-genie template: metadata: labels: app: api-genie spec: containers: - name: api-genie image: api-genie-integration:latest ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: api-genie spec: type: LoadBalancer ports: - port: 8080 targetPort: 8080 selector: app: api-genie
Conclusão
Neste tutorial, você aprendeu a integrar o Genie Framework em seus projetos de microserviços utilizando Spring Boot, Docker e Kubernetes. Passamos por todas as etapas desde a criação da aplicação até sua dockerização e implantação em um cluster Kubernetes. A automação de processos e a abstração proporcionada pelo Genie Framework são ferramentas poderosas para otimizar o desenvolvimento ágil. Com esses conhecimentos, você está bem equipado para criar e gerenciar aplicações escaláveis e de fácil manutenção.