Introdução

Neste tutorial, vamos explorar como integrar Groovy, uma linguagem de programação que se destaca pela sua simplicidade e flexibilidade, com o framework Spring Boot, amplamente utilizado para desenvolver aplicações web de forma ágil e eficiente. A combinação de Groovy e Spring Boot permite criar aplicativos mais concisos e práticos, aproveitando a sintaxe simplificada do Groovy e o poder do ecossistema Spring. Neste guia, abordaremos desde a configuração do projeto até a implementação de um exemplo prático de aplicação web, incluindo a criação de endpoints REST, interação com o banco de dados e testes unitários. Você aprenderá a desenvolver uma aplicação robusta, aproveitando as melhores práticas de desenvolvimento ágil.

Etapas

  1. Configuração do Ambiente de Desenvolvimento

    Antes de começarmos, você precisa garantir que possui o JDK (Java Development Kit) e o Maven instalados em seu computador. Além disso, você deve ter o Groovy instalado. Para verificar as versões do JDK e do Maven, utilize os comandos `java -version` e `mvn -version`. Para instalar o Groovy, você pode seguir as instruções disponíveis no site oficial do Groovy.

    commands
    # Verifique as versões instaladas
    java -version
    mvn -version
    groovy -version

  2. Criação do Projeto Spring Boot com Groovy

    Utilize o Spring Initializr para gerar um novo projeto Spring Boot em Groovy. Configure as seguintes opções: **Project**: Maven, **Language**: Groovy, **Spring Boot**: última versão estável, **Packaging**: Jar. Adicione as dependências ‘Spring Web’, ‘Spring Data JPA’ e ‘H2 Database’. Faça o download e extraia o projeto em seu local 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>app-groovy-spring</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>app-groovy-spring</name>
      <description>Aplicação com Groovy 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>

  3. Configuração do Banco de Dados H2

    Abra o arquivo `application.properties` e adicione as seguintes configurações para o H2, definindo um banco de dados em memória e habilitando o console web para visualização dos dados.

    application.properties
    spring.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

  4. Criação da Entidade `Produto` em Groovy

    Crie uma nova classe chamada `Produto.groovy` que representa a entidade no banco de dados. Utilize anotações JPA para mapear a classe à tabela correspondente.

    Produto.groovy
    package com.example.appgroovyspring.model
    
    import javax.persistence.*
    
    @Entity
    @Table(name = 'produtos')
    class Produto {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        Long id
    
        @Column(nullable = false)
        String nome
    
        @Column(nullable = false)
        Double preco
    }

  5. Criação do Repositório `ProdutoRepository`

    Implemente a interface `ProdutoRepository` que estende `JpaRepository`, provendo acesso aos dados do `Produto`.

    ProdutoRepository.groovy
    package com.example.appgroovyspring.repository
    
    import com.example.appgroovyspring.model.Produto
    import org.springframework.data.jpa.repository.JpaRepository
    import org.springframework.stereotype.Repository
    
    @Repository
    interface ProdutoRepository extends JpaRepository<Produto, Long> {
    }

  6. Implementação do Serviço `ProdutoService`

    Crie uma classe de serviço chamada `ProdutoService.groovy` que encapsula a lógica de negócios da sua aplicação. Ela usará o `ProdutoRepository` para interagir com os dados do produto.

    ProdutoService.groovy
    package com.example.appgroovyspring.service
    
    import com.example.appgroovyspring.model.Produto
    import com.example.appgroovyspring.repository.ProdutoRepository
    import org.springframework.beans.factory.annotation.Autowired
    import org.springframework.stereotype.Service
    
    @Service
    class ProdutoService {
        @Autowired
        ProdutoRepository produtoRepository
    
        List<Produto> findAll() {
            return produtoRepository.findAll()
        }
    
        Optional<Produto> findById(Long id) {
            return produtoRepository.findById(id)
        }
    
        Produto save(Produto produto) {
            return produtoRepository.save(produto)
        }
    
        Produto update(Long id, Produto produtoDetails) {
            def produto = produtoRepository.findById(id).orElseThrow { new RuntimeException('Produto não encontrado') }
            produto.nome = produtoDetails.nome
            produto.preco = produtoDetails.preco
            return produtoRepository.save(produto)
        }
    
        void deleteById(Long id) {
            produtoRepository.deleteById(id)
        }
    }

  7. Implementação do Controlador `ProdutoController`

    Crie a classe `ProdutoController.groovy` para expor os endpoints da API REST e permitir operações CRUD sobre os produtos.

    ProdutoController.groovy
    package com.example.appgroovyspring.controller
    
    import com.example.appgroovyspring.model.Produto
    import com.example.appgroovyspring.service.ProdutoService
    import org.springframework.beans.factory.annotation.Autowired
    import org.springframework.http.ResponseEntity
    import org.springframework.web.bind.annotation.*
    
    @RestController
    @RequestMapping('/api/produtos')
    class ProdutoController {
        @Autowired
        ProdutoService produtoService
    
        @GetMapping
        List<Produto> getAllProdutos() {
            return produtoService.findAll()
        }
    
        @GetMapping('/{id}')
        ResponseEntity<Produto> getProdutoById(@PathVariable Long id) {
            return produtoService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build())
        }
    
        @PostMapping
        Produto createProduto(@RequestBody Produto produto) {
            return produtoService.save(produto)
        }
    
        @PutMapping('/{id}')
        ResponseEntity<Produto> updateProduto(@PathVariable Long id, @RequestBody Produto produtoDetails) {
            return ResponseEntity.ok(produtoService.update(id, produtoDetails))
        }
    
        @DeleteMapping('/{id}')
        ResponseEntity<Void> deleteProduto(@PathVariable Long id) {
            produtoService.deleteById(id)
            return ResponseEntity.noContent().build()
        }
    }

  8. Implementação de Testes Unitários

    Crie a classe de testes `ProdutoServiceTest.groovy` para validar a lógica do serviço. Utilize o JUnit e Mockito para simular as interações com o repositório.

    ProdutoServiceTest.groovy
    package com.example.appgroovyspring.service
    
    import com.example.appgroovyspring.model.Produto
    import com.example.appgroovyspring.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.Optional
    import static org.junit.jupiter.api.Assertions.*
    import static org.mockito.Mockito.*
    
    class ProdutoServiceTest {
        @InjectMocks
        ProdutoService produtoService
    
        @Mock
        ProdutoRepository produtoRepository
    
        @BeforeEach
        void init() {
            MockitoAnnotations.openMocks(this)
        }
    
        @Test
        void testFindAll() {
            def produto1 = new Produto(id: 1, nome: 'Produto 1', preco: 10.0)
            def produto2 = new Produto(id: 2, nome: 'Produto 2', preco: 20.0)
            when(produtoRepository.findAll()).thenReturn([produto1, produto2])
    
            def produtos = produtoService.findAll()
            assertEquals(2, produtos.size())
            verify(produtoRepository, times(1)).findAll()
        }
    
        // Adicione mais testes para os métodos findById, save, update e deleteById
    }

  9. Executando a Aplicação e Testes

    Compile e execute a aplicação usando o Maven. Teste os endpoints da API utilizando um cliente como Postman ou cURL.

    commands
    # Compilar e executar a aplicação
    mvn spring-boot:run
    # Executar os testes unitários
    mvn test

    curl_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/produtos

Conclusão

Neste tutorial, você aprendeu como integrar Groovy com Spring Boot para desenvolver uma aplicação web completa, desde a configuração inicial até a implementação de endpoints REST e testes unitários. O uso do Groovy permitiu que escrevêssemos menos código de forma mais expressiva, desejando uma abordagem mais ágil ao desenvolvimento. Com este conhecimento, você está apto a construir aplicações web mais simples e eficazes, aproveitando os benefícios que Groovy e Spring Boot oferecem.

Hashtags

#Groovy #SpringBoot #DesenvolvimentoÁgil #APIs #JUnit #TestesUnitários