Transformando seus scripts Groovy em microserviços com Spring Boot!

Quando o Spring Boot foi lançado este veio com uma ferramenta chamada "Spring CLI". Brinquei um pouco com ela na época mas confesso que não vi muita graça: até agora.

Dentre as suas funcionalidades há uma bastante interessante: a possibilidade de criarmos microserviços usando scripts escritos em Groovy. Mas atenção: digo aqui microserviços MESMO: não use esta solução para seus amáveis monolitos.

O tipo de aplicação que podemos criar com base nesta estratégia não chamaria sequer de microserviços, mas nanoserviços. Aplicações realmente úteis, compostas por um número muito pequeno de endpoints (um, dois no máximo) que são simples e podem quebrar diversos galhos na sua infraestrutura.

Não espere que este post vá lhe servir de guia completo para este tipo de solução: a ideia é apenas apresentar a vocês esta possibilidade, mas não fiquem tristes, colocarei links que lhes ajudarão a aprender mais sobre o assunto durante e após sua leitura.

Spring CLI?

É muito curioso que com tantos tutoriais, cursos e livros sobre Spring e Spring Boot (me salvo nesta: meu primeiro livro foi sobre o Spring Framework, não Spring Boot!) pouca gente mencione esta ferramenta. Talvez seja por que todo mundo pense da mesma forma na hora de escrever... talvez por que seja algo que não envolva a linguagem Java, mas sim Groovy... não entendo (mas tenho minhas suspeitas).

Mas fato é que apesar de pouco falado o Spring CLI existe desde que o Boot foi lançado. E era inclusive usado na época para demonstrar o poder do framework como algo super produtivo, bem na mesma pegada que o povo demonstrava o Node.js quando saiu.

Se você já programou em Grails ou Express o Spring CLI lhe parecerá familiar. É uma interface de linha de comando (Command Line Interface) que você instala e pode executar as seguintes funções:

  • Criar novos projetos baseados no Spring Boot, tal como faria no site https://start.spring.io só que com sua linha de comando.
  • Executar "Spring Boot Groovy Scripts" (nosso assunto aqui).
  • Empacotar sua aplicação (seja ela Java ou estes scripts que menciono acima).
  • Outras pequenas funções que li rapidamente e minha preguiça impediu que me aprofundasse nelas.

O recurso ainda está ativo (e em contínuo desenvolvimento!) no Spring Boot e você pode ler sua documentação neste link em sua versão mais atual, ou seja, se é mantido até hoje com certeza muita gente usa!

Instalando o Spring CLI

Há duas formas de fazer isto: a fácil, que ensino aqui e outra que você pode ver no link que mencionei agora há pouco. A fácil e que recomendo é usando o Sdkman (não conhece? Escrevi um guia a respeito que você pode ler aqui: https://www.itexto.com.br/guias/?guia=configurando-seu-ambiente-de-desenvolvimento-java-com-sdkman ).

Execute o comando a seguir com o sdkman:

sdk install springboot 2.2.2.RELEASE

Para testar sua instalação execute o comando a seguir:

spring --version

Será apresentada para você a versão instalada. Mencionei aqui que vamos usar Groovy, certo? Você não precisa ter a linguagem instalada em seu computador. O Spring CLI já inclui tudo o que você precisa para poder trabalhar.

Nosso primeiro "Olá mundo!"

Cabe aqui um "Olá mundo" para mostrar a simplicidade do código que escrevemos para termos um "nano serviço" em execução com o Spring CLI. Nosso pimeiro "Olá mundo" pode ser visto a seguir:

@RestController
class OlaMundo {
    @RequestMapping("/")    
    String olaMundo() { 
      "Que negócio simples!"}
}

Repare que não há instruções import. Não é necessário importar as classes: o próprio CLI vai importá-las para você de forma automática.

Note que é apenas uma classe Groovy padrão com algumas anotações: as mesmas que usamos ao implementar endpoints com o Spring tradicional: @RestController pra informar que a classe é um controlador e @RequestMapping para informar que aquele método disponibiliza um endpoint.

E como fazemos para executar este script? Usando o comando spring novamente.

spring run ola-mundo.groovy

A sua linha de comando irá apresentar uma saída que se você já programou com Spring com certeza já conhece:

E se acessar o endereço http://localhost:8080, o que você vai ver?

Paramos por aqui com este exemplo. Vamos para algo mais útil.

Um exemplo um pouco mais útil: monitorando o servidor usando Groovy e Actuator

No exemplo anterior você viu essencialmente como usando Groovy criamos um nano serviço com Spring Boot, certo? Se é Spring Boot, podemos usar todos dos seus recursos como o Actuator, por exemplo: que nos permite monitorar os serviços que implementamos.

Então que tal implementarmos aqui um micro serviço que verifique se tudo está ok no nosso servidor? Ele poderia usar as validações padrões do Actuator e ainda implementar nossas próprias regras de validação. Imagine que por alguma razão é necessária a presença do arquivo felicidade.txt no diretório home do usuário responsável por executar a aplicação. Como faríamos isto?

Já que estamos falando de Spring, será que nossos scripts podem ter seus próprios beans? A resposta é sim: observe o código que escrevi (está tudo em um mesmo arquivo chamado monitor.groovy):

Há algumas coisas interessantes aqui que você deve prestar atenção. Talvez você não conheça esta anotação: @grab . Ela faz parte de um recurso incrível do Groovy chamado Grape. Enquanto na maior parte das aplicações você usa soluções como Maven ou Gradle para resolver as suas dependências, como você faria se precisasse escrever apenas um script? Faria sentido ter um arquivo pom.xml ou build.gradle só para executá-lo? Não! Se você incluir a anotação @grab do Groovy em seu script, ele irá incluir estas dependências no classpath de forma automática durante a execução: lindo, né?

No caso, eu precisei incluir as dependências do Actuator no projeto e importar duas classes para implementar o nosso HealthIndicator: Health e... HealthIndicator.

E dali pra baixo você que já conhece o Spring não verá novidade alguma: temos um componente e um controlador. Mas observou que este controlador é uma classe vazia sem nenhum endpoint exposto? Precisamos dela para que o Spring CLI execute nossa aplicação. Experimente executar o script acima sem o controlador para ver o que ocorre.

Com nosso código pronto, basta executar agora:

spring run monitor.groovy

E acessando http://localhost:8080/actuator/health temos a seguinte saída:

Mas e as configurações?

Mas se você já usou o Actuator antes deve ter observado que esta não é a saída padrão do mesmo. Então, aonde coloquei as configurações? Simples: você pode seguir uma convenção: se no diretório em que seu script se encontra existir uma pasta chamada config, basta deixar ali um arquivo application.properties ou application.yml. Seguem as minhas configurações:

management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

Você também pode passar suas configurações por linha de comando ou variáveis de ambiente, exatamente como faria em uma aplicação baseada em Spring Boot por que, bem: esta é uma aplicação baseada em Spring Boot. Sugiro a leitura deste post do Baeldung sobre o Spring CLI que descreve em maiores detalhes como estas configurações se aplicam.

Minha aplicação pode ter mais de um arquivo de script?

Claro! Como você faz para executar a aplicação então? Bem simples.

spring run *.groovy

Ou qualquer outra expressão que seu shell aceite para a seleção de múltiplos arquivos.

Gerando um arquivo JAR executável

Executar o seu script com o CLI é bastante útil no ambiente de desenvolvimento, mas em produção não é uma boa ideia. Sendo assim, como você faz para implantar a sua aplicação? Basta usar o comando spring jar com a seguinte sintaxe essencial:

spring jar [nome do arquivo .jar] [scripts que compõem sua aplicação]

Nosso último exemplo poderia ser empacotado portanto com o comando a seguir:

spring jar monitor.jar monitor.groovy

Feito: agora basta executar o comando java -jar monitor.jar e nossa aplicação estará disponível. Neste arquivo estarão todas as dependências necessárias para a execução do projeto.

Apenas por curiosidade, o arquivo gerado para o nosso monitor tinha 24Mb de tamanho. Um overhead significativo para algo tão pequeno, huh?

Aplicações mais práticas

Não recomendo o uso do Spring CLI para a criação de aplicações complexas, isto é, compostas por uma quantidade significativa de scripts (3 ou mais). Se você quer usar Groovy como linguagem no desenvolvimento de aplicações baseadas em Spring Boot, saiba que ele oferece total suporte, sendo inclusive uma das opções quando criamos um novo projeto no site Spring Initializr:

Mas existe um nicho de aplicações para o qual este tipo de desenvolvimento cai como uma luva. É algo para o qual eu já uso Node.js faz um bom tempo inclusive: consiste em aplicações que sejam essencialmente utilitárias, isto é, que desempenhem uma única função e cuja interação com as mesmas se dê através da disponibilização de um conjunto ínfimo de endpoints. Seguem alguns exemplos:

  • Monitoramento de servidores, como o que escrevi acima.
  • Scripts que executem tarefas agendadas e que cujo resultado do processamento você precise acompanhar.
  • Ferramentas de integração: quando implemento webhooks, por exemplo, costumo ter um destes scripts que sirva para me mostrar como é o corpo das requisições recebidas assim como seus cabeçalhos.
  • Ferramenta de consultas simples a bases de dados: algo que retorne, por exemplo, se ocorreu determinado evento em um período de tempo que não justificaria sua inclusão na aplicação.
  • Seu script usa classes que façam parte de uma outra aplicação: você pode incluí-las no seu classpath tanto na execução quanto no empacotamento da sua solução.

Podem ser também simplesmente aplicações compostas por um único endpoint. Fiz uma prova de conceito, por exemplo, para o /dev/All que era a implementação do RSS do site e funcionou muito bem. Resumindo: é uma ferramenta para a construção de microserviços (eu diria nano) que sejam realmente pequenos.

Para saber mais

Achou legal esta possibilidade? Quer se aprofundar a respeito? Então seguem alguns links que me ajudaram e com certeza vão te ajudar também.

Introduction to Spring Boot CLI - Baeldung - excelente texto por sinal - https://www.baeldung.com/spring-boot-cli

Documentação do Actuator, que usei neste post como exemplo - https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html

Conhecia a solução? Já a experimentou? Compartilhe conosco sua experiência com esta!

15