Por que os desenvolvedores Java devem dar uma chance ao Grails?
Publicados: 2022-03-11Java tem um ecossistema que amadureceu ao longo de anos de desenvolvimento, estabelecendo-o como uma das plataformas mais confiáveis existentes. No entanto, falta os meios necessários para fazer o trabalho rapidamente, especialmente para coisas como aplicativos da web. Na tentativa de evitar frustrações com esses tipos de problemas, os desenvolvedores geralmente optam por linguagens de implementação e seus frameworks web modernos, como Ruby com Ruby on Rails, Python com Django e assim por diante. Ao contrário do Java, eles fornecem um caminho muito mais simplificado para a criação de um aplicativo da Web.
Felizmente, para desenvolvedores Java que desejam construir aplicativos da Web, existe uma maneira melhor e envolve Grails. Neste artigo, veremos como Grails com Groovy é uma alternativa viável no domínio da JVM. Veremos alguns exemplos em que o Grails é atraente para nós como desenvolvedores Java e pode tentar alguém a tentar também.
A história
Em uma startup em que trabalhei, tivemos exatamente esse problema. Tínhamos um aplicativo Spring que estava se tornando uma dor de cabeça para trabalhar. Com ele crescendo cada vez mais, logo descobrimos que refatorar e adicionar funcionalidades estava nos levando muito mais tempo do que deveria. A combinação disso com algumas outras motivações nos levou a decidir reescrever nosso aplicativo principal. Também estávamos abertos a mudar ou substituir a pilha de tecnologia existente. O Grails parecia uma escolha viável, pois é executado na JVM e é construído com base em tecnologias que já conhecíamos. Ele usa a linguagem de programação Groovy, mas ao mesmo tempo permite misturá-lo com Java. Então nós nos arriscamos.
Velocidade máxima a frente
Uma coisa em que o Grails realmente se destaca é facilitar o início de um novo projeto. É tão simples quanto executar um comando que cria a estrutura do projeto com todas as pastas necessárias para as classes que você adicionará posteriormente. Adicionar classes de modelo, controladores, serviços e páginas da Web exige um esforço igualmente mínimo. A única coisa que você precisa cuidar é nomear e colocar as coisas corretamente. Ao contrário do Java, praticamente não há código clichê que precise estar lá apenas porque precisa estar. Isso é parcialmente possível usando Spring e Hibernate, que são dois dos pilares do Grails, bem como o conceito de codificação por convenção. Para executar o projeto, Grails vem junto com o Apache Tomcat como servidor de desenvolvimento. Tudo o que precisamos fazer é executar o projeto em nosso IDE e o servidor será acionado com nosso código implantado. Além disso, o Object Relational Mapping (GORM) do Grails com Hibernate cuidará da criação do banco de dados para nós. Para usar um banco de dados existente, precisamos configurar as propriedades de conexão JDBC ou apenas deixá-lo por padrão para usar uma instância na memória. Uma vez que o servidor com Grails esteja rodando (requer um pouco mais do que um aplicativo Spring MVC), podemos modificar o código e a funcionalidade de implantação a quente manterá nossa sessão de depuração equipada com a versão mais recente. As únicas classes que não podem ser recarregadas dessa maneira são as classes de entidade.
O preenchimento do banco de dados pode ser feito usando scripts SQL, mas isso pode ser tedioso. Todos os projetos Grails contêm uma classe Bootstrap que será executada quando nosso aplicativo for executado. Nesta classe, podemos armazenar ou modificar dados e, assim, inicializar nosso estado de aplicação. Isso provou ser muito útil para nós, então temos alguns casos de teste na versão de desenvolvimento imediatamente.
Manipulando dados
Uma das coisas que imediatamente chamou nossa atenção com o Grails foi a facilidade de trabalhar com dados. A leitura do banco de dados é uma tarefa que precisa ser feita repetidamente. E muitas vezes é simples. Como buscar uma ou mais entidades que atendem a determinados critérios e depois agregá-los. Por que não usar um localizador dinâmico para isso? É uma maneira de consultar dados onde os métodos são criados dinamicamente em tempo de execução. Tudo o que você precisa fazer é seguir uma convenção de nomenclatura.
def users = User.findAllByLastNameLikeOrAgeGreaterThan('Doe%', 30)
A linha acima da linha buscará todos os objetos User com sobrenome começando com “Doe” ou idade maior que 30. Sim, não é um caso muito sofisticado, mas você entende a essência.
E se quiséssemos filtrar esta lista adicionalmente para aquelas que possuem a propriedade “failedLogins” maior que 10? E se quiséssemos classificá-los pela data de criação? E se quiséssemos concatenar seus primeiros nomes ou encontrar a idade máxima dos usuários retornados?
users = users.findAll() { it.failedLogins > 10 } users = users.sort { it.dateCreated } def firstNamesString = users.firstName.join(', ') def maximumAge = users.age.max()
Os exemplos acima podem parecer simples, mas mostram como o Grails pode ser poderoso para consultar, filtrar e manipular dados. No Java 8, você pode obter resultados semelhantes para alguns desses casos, mas ainda exigirá mais código do que o Grails.
Às vezes eu quero criar diferente
Um construtor dinâmico ou construtor de argumento nomeado é um recurso que muitos de nós queríamos ter em Java. É bom definir quais construtores uma determinada classe permite, mas em muitos casos você só quer definir algumas propriedades e obter a maldita instância. Groovy adiciona um construtor especial para cada entidade que basicamente pega a elegância de um mapa como entrada e define as propriedades com as entradas do mapa.
def Person = new Person(name: 'Batman', age: 57)
Essa abordagem leva a um código muito mais expressivo e evita a necessidade de todo o código clichê do construtor.
E BTW, aqui estão alguns exemplos da grandiosidade e elegância dos mapas do Groovy:
def emptyMap = [:] def map = [bread:3, milk:5, butter:2] map['bread'] = 4 map.milk = 6
Este é outro exemplo de como o código pode ser curto e simples, mas poderoso. Ele mostra como a inicialização em linha pode ser usada e como os valores do mapa podem ser manipulados de maneira semelhante às propriedades do objeto. Não há necessidade de chamar métodos Java tradicionais para manipulação básica, a menos que você realmente queira.
Precisamos de mais potência!
Claro, não existe um framework que possa fazer tudo, mas quando estamos preenchendo as lacunas, devemos ver o que mais já pode estar disponível antes de tentar implementar nossa própria solução. Para expandir nosso arsenal de funcionalidades baseadas em Grails, podemos usar Plugins Grails. A instalação de um plugin é feita simplesmente adicionando outra linha na classe BuildConfig
que está presente em todo projeto Grails (a convenção de código ataca novamente!).

compile ':spring-security-core:2.0-RC4'
A linha acima adiciona o núcleo de segurança Spring ao nosso aplicativo e praticamente não há mais configuração necessária para incorporar essa funcionalidade.
Dito isto, deixe-me falar sobre um caso que tivemos que lidar. Precisávamos implementar uma pesquisa que abrangesse várias entidades de dados. Grails tem um plugin Elasticsearch que é muito fácil de usar. Como mencionado anteriormente, só precisamos referenciar o plugin no arquivo de configuração e pronto. Se quisermos procurar por entidades de uma determinada classe, basta adicionar uma propriedade estática “pesquisável” a essa classe. E se quisermos, podemos até limitar as propriedades que poderão ser pesquisadas.
class User { static searchable = { only = name } String name Double salary }
É tão pouco código, mas sob o capô, Grails e o plug-in Elasticsearch indexarão automaticamente todos os usuários por nome e nos permitirão pesquisar por nome. A chamada de pesquisa real também é muito concisa:
User.search("${params.query}")
Se não quisermos, nunca teremos que tocar no índice Lucene. Tudo será feito auto-magicamente para nós. O plug-in ainda possui uma API para exibir os resultados da pesquisa - pode destacar a correspondência encontrada no texto pesquisado. Este é apenas um exemplo de como um plugin pode fornecer um enorme pacote de funcionalidades que podem nos tornar muito mais eficientes, evitando a necessidade de implementá-lo por conta própria.
Ainda precisamos de mais energia
Os plugins são ótimos, mas às vezes não precisamos de um plugin inteiro, queremos apenas algo extra. Você se lembra da última vez que quis ter um método adicional em uma classe Java existente, mas não queria (ou não podia) estendê-los/substituí-los? No Groovy, você pode adicionar métodos e propriedades a classes existentes, ou mesmo apenas algumas instâncias delas. Por exemplo, você pode adicionar um método de formatting
à classe java.util.Date
que é incrível quando você quer formatar datas de forma consistente e não quer escrever classes util estáticas ou definir vários filtros.
Date.metaClass.formatDate = { delegate.format("dd.MM.yyyy") }
E se você quiser ordenar uma lista de usuários por um valor calculado e precisar disso apenas em um caso (ou seja, adicionar um novo método na classe User seria poluente)? Você pode adicionar uma propriedade em cada uma dessas instâncias e depois classificar ou filtrar a coleção por essa propriedade:
user.metaClass.computedProp = 312 * 32 * 3
Os autores do Groovy já adicionaram muitos aprimoramentos a algumas das principais classes Java, portanto, não precisamos. Abaixo estão alguns exemplos.
Usando “menos” para remover todos os elementos de uma coleção que estão presentes em outra coleção.
assert [1, 2, 3, 4, 4, 5] - [2, 4] == [1, 3, 5]
Métodos adicionais para manipular objetos java.util.Date
que são úteis muitas vezes, como adicionar/subtrair dias de datas ou obter/definir um determinado campo da data sem convertê-lo em Calendar
ou usar bibliotecas adicionais.
def yesterdayAllMyTroublesSeemedSoFarAway = new Date() - 1 def myAwesomeAnniversaryYear = myAwesomeDate[Calendar.YEAR] + 1 myAwesomeDate.set(year: myAwesomeAnniversaryYear, second: 0)
Quando você quiser realmente ser descritivo com a manipulação de data, basta usar a classe TimeCategory
adicionada ao Groovy:
use (TimeCategory) { println 1.minute.from.now println 10.hours.ago def someDate = new Date() println someDate - 3.months }
Um martelo e um prego
Depois, há os IDEs. GGTS e IntelliJ IDEA baseados em Eclipse são configurados para trabalhar com Grails. Eles entendem a estrutura do projeto (e o ajudarão a navegar pelas pastas e recursos) e têm atalhos para os comandos que você usará com mais frequência (por exemplo, adicionar controlador, adicionar uma página, executar um projeto etc.). Com Grails você executará comandos (para executar um projeto ou configurar uma nova funcionalidade de plugin) e precisará de configurações diferentes, que também são cobertas pelos IDEs. O autocompletar de código funciona bem em páginas de modelo da web do Grails, onde você frequentemente fará referência a controladores e ações. Existem também outros IDEs que podem ser usados com Grails, como Netbeans, TextMate, Emacs e outros.
E o Lado Negro?
Assim como em tudo na vida, há ressalvas com Grails também. Há muita mágica sendo feita sob o capô, o que muitas vezes pode ser uma coisa boa, mas às vezes o resultado não será o que você esperava. Bugs acontecerão apenas por não usar digitação (sim, os tipos são opcionais no Groovy) e por não ser cuidadoso o suficiente. E talvez você não notará um erro até que seja tarde demais. Além disso, é muito tentador escrever frases curtas para impressionar seus colegas de trabalho. E você mesmo. Mas essas poderosas linhas de código podem não ser tão autoexplicativas para seus colegas de trabalho. Ou até mesmo para si mesmo em alguns meses. É por isso que acho que Grails exige mais disciplina de programação do que alguns dos frameworks mais tradicionais.
Tempo é dinheiro
A codificação não deve levar mais tempo apenas porque sua estrutura atual exige. Especialmente com o número cada vez maior de startups nos dias de hoje, é importante focar nas tarefas que realmente importam e ser o mais eficiente possível. Tempo é realmente dinheiro e tempo de mercado é fundamental. Você precisa ser capaz de agir rapidamente e implementar a solução antes que o tempo acabe e sua concorrência o vença.
Meus amigos que trabalham com Ruby on Rails ou Python/Django há muito me dizem como essas tecnologias são legais. E realmente parecia bobo pensar quanto mais tempo levei em Java para escrever código que armazena algo no banco de dados e o exibe em uma página da web. Grails pode realmente ser uma resposta útil. Não é que você não possa fazer isso com Java puro, Spring MVC e Hibernate. Você poderia. Seu aplicativo pode até ser executado um pouco mais rápido. Mas você fará o trabalho mais rápido com Grails.