logoJawr

Modularizando JavaScript com Spring MVC e Jawr

javascript-logoEste post inicia uma série na qual vou expor técnicas que visam aumentar a manutenibilidade de código Javascript. Convenhamos: é uma linguagem de programação legal, porém muitas vezes o hype que a envolve nos impede de ver seus aspectos negativos. Neste post tratarei de uma das cicatrizes da linguagem que é a dificuldade que enfrentamos na modularização do código.

O problema: modularizar JavaScript usando Spring MVC

Se você tem a sorte de trabalhar com Grails tem à sua disposição uma solução maravilhosa que é o plugin resources que nos permite definir “módulos Javascript”. Infelizmente do lado Spring da cerca não temos algo tão popular. O que é um módulo Javascript?

Uma unidade de código que funciona em conjunto.

Muitas vezes esta unidade não é apenas um arquivo, mas vários, e é neste ponto que o problema começa a se manifestar. Imagine um módulo composto por dois arquivos: biblioteca.jsbiblioteca2.js. Sua equipe pode ter achado interessante dividi-lo em dois arquivos para paralelizar o esforço e com isto evitar todos aqueles incômodos relacionados ao merge de arquivos. Nesta situação, toda vez que você precisa usar este módulo, irá inserir em suas páginas código similar ao exposto a seguir:


<script type="text/javascript" src="/resources/js/biblioteca.js"></script>
<script type="text/javascript" src="/resources/js/biblioteca2.js"></script>

Ou então você poderia ter algum script que unisse os dois arquivos. O problema é que seria necessário modificar o seu processo de build e também fornecer garantias de que o arquivo gerado fosse sempre o mais atualizado possível (não é uma solução tãão bacana assim).

Agora, voltemos ao nosso exemplo. Imagine que este nosso módulo dependa do jQuery. Neste caso teríamos sempre de escrever o seguinte código em nossas páginas:


<!-- jQuery sempre irá ser carregado primeiro -->
<script type="text/javascript" src="/resources/js/jQuery.js"></script>
<script type="text/javascript" src="/resources/js/biblioteca.js"></script>
</span><script type="text/javascript" src="/resources/js/biblioteca2.js"></script>

Ainda pior: imagine que a ordem de carregamento dos arquivos biblioteca.jsbiblioteca2.js seja importante. Agora sua equipe precisa ser informada a respeito. Se for uma aplicação de uma única página, não será lá um grande problema, mas imagine uma aplicação maior, com mais de um template, etc. A coisa começa a se complicar.

A imagem a seguir expõe bem a situação do nosso projeto. Temos uma biblioteca composta por dois arquivos que depende de uma terceira:

jawr_dependencias

Não seria bacana se houvesse uma ferramenta que nos permitisse resolver os problemas a seguir de uma forma simples?

  • Documentar as dependências entre os nossos arquivos Javascript de tal forma que seja fácil para a equipe entender a organização interna do projeto.
  • Garantir que os arquivos sejam sempre carregados na ordem correta.
  • De alguma maneira otimizar o modo como estes arquivos são enviados ao browser: compressão via gzip, talvez até mesmo um merge dos arquivos.

Jawr entra em cena

logoJawr

Jawr é uma ferramenta que tem como objetivo resolver os três problemas que expus acima e mais alguns. Neste post irei tratar de uma parte bem pequena deste projeto: aquela que lida com Javascript. A grosso modo Jawr é um servlet que iremos inserir em nosso projeto fictício. Este servlet organizará nossos módulos Javascript em bundles.

O que é um bundle? É um módulo, tal como expus acima. Mais do que isto, um bundle alguns atributos fundamentais do nosso módulo:

  • Que arquivos compõem o nosso módulo
  • Em que ordem estes arquivos devem ser carregados
  • Quais as dependências do nosso bundle, isto é, que código este precisa para funcionar?

Voltando ao nosso projeto percebe-se que há dois bundles: biblioteca e jQuery, que podemos representar gráficamente tal como na imagem a seguir:

Nossos bundles

Nossos bundles

Poderíamos pensar em um bundle único composto pelos nossos arquivos da biblioteca e o do jQuery. O problema é que sabemos que jQuery será usado por diversos outros pontos da nossa aplicação: sendo assim é interessante que modularizemos esta parte a fim de que seja reaproveitada em outras partes do projeto.

Incluindo Jawr em nosso projeto

Nosso projeto é baseado em Maven. Sendo assim, para incluirmos o Jawr basta adicionar a dependência no arquivo pom.xml tal como no exemplo a seguir:

<dependency>
    <groupId>net.jawr</groupId>
    <artifactId>jawr</artifactId>
    <version>3.3.3</version>
</dependency>

Como disse logo acima, Jawr é essencialmente um servlet. Sendo assim temos também de alterar o arquivo web.xml para que fique similar ao exposto a seguir:

<!-- Servlet para lidar com Javascript -->
<servlet>
   <servlet-name>JavascriptServlet</servlet-name>
   <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class>

		<!-- Aonde se encontra o arquivo de configuracao -->
   <init-param>
       <param-name>configLocation</param-name>
       <param-value>/jawrJavascript.properties</param-value>
   </init-param>
   <init-param>
       <param-name>mapping</param-name>
       <param-value>/bundle/js/</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>
<!-- O mapeamento de URL -->	
<servlet-mapping>
   <servlet-name>JavascriptServlet</servlet-name>
   <url-pattern>/bundle/js/*</url-pattern>
</servlet-mapping>

Preste muita atenção no mapeamento de URL. Na documentação oficial do Jawr este é configurado para que lide com todos os recursos que terminem com a extensão .js. O problema com esta abordagem é que muitas vezes não queremos que todos os nossos arquivos Javascript sejam carregados como bundles. Talvez você queira ir adotando aos poucos a ferramenta em seu projeto (esta é a principal razão que vejo). Em nosso caso, Jawr só irá lidar com aqueles recursos Javascript que se encontrem na url /bundle/js/*. Nota importante: repare no parametro de inicialização mapping. Se for usar uma configuração como esta, este obrigatóriamente deve estar definido.

Configurando os bundles

No mapeamento do servlet foi incluído um parâmetro chamado configLocation. Em nosso projeto baseado em Maven este arquivo se encontra em /src/main/resources/jawrJavascript.properties. É neste arquivo que iremos definir todos os nossos bundles. Abaixo está um exemplo deste arquivo:

# Altere aqui caso esteja no seu ambiente de desenvolvimento
jawr.debug.on=false

# Devemos enviar os bundles compactados?
jawr.gzip.on=true

# De quantos em quantos segundos o servlet deve verificar se as configuracoes foram
# alteradas. Extreammente util em tempo de desenvolvimento!
jawr.config.reload.interval=30

# Primeiro bundle de exemplo: jQuery
# O identificador do bundle sempre é o que aparece antes do ‘.id’
# neste caso, é jquery
jawr.js.bundle.jquery.id=/bundle/js/jQuery.js
jawr.js.bundle.jquery.mappings=/resources/js/jquery-2.1.0.min.js

# Incluindo uma dependencia
jawr.js.bundle.biblioteca.id=/bundle/js/biblioteca.js
jawr.js.bundle.biblioteca.mappings=/resources/js/biblioteca.js, /resources/js/biblioteca2.js
jawr.js.bundle.biblioteca.dependencies=jquery

Um bundle Javascript é definido no arquivo com o prefixo jawr.js.bundle.[identificador do bundle]. A primeira linha, que termina com .id define como será a URL que define o nosso bundle. O bundle jQuery, por exemplo, sempre será carregado quando a URL /bundle/js/jQuery.js for acionada, enquanto o bundle biblioteca, pela URL /bundle/js/biblioteca.js.

Voltemos nossa atenção para o bundle biblioteca. A segunda linha da sua definição (mappings), define quais os arquivos que o compõe e a ordem na qual devem ser carregados. A terceira linha define quais as suas dependências. Neste caso, apenas uma: o bundle jquery.

Tendo feito isto temos todos os bundles em nosso projeto prontos para serem usados. O próximo passo é trabalhar no arquivo JSP.

Alterando o arquivo JSP

O projeto Jawr vem com uma biblioteca de tags bastante útil. Abaixo podemos ver um exemplo de sua aplicação:

<%– A declaração da biblioteca de tags –%>
<%@ taglib uri="http://jawr.net/tags" prefix="jwr" %>

<%– Carregando o bundle biblioteca –%>
<jwr:script src="/bundle/js/biblioteca.js"/>

E o que ocorre quando carrego a página? Obtenho o resultado a seguir:

<script type="text/javascript" src="/itexto/bundle/js/gzip_N1063700552/bundle/js/jQuery.js" ></script>
<script type="text/javascript" src="/itexto/bundle/js/gzip_N745101183/bundle/js/biblioteca.js" ></script>

Primeiro será inserida a dependência do bundle biblioteca e, em seguida, o código fonte do bundle biblioteca. Repare nas URLs: o Jawr irá automáticamente cachear os recursos Javascript. E sabem o que é mais legal? Ele também envia o Javascript comprimido (se o modo de depuração estiver desativado (veja as notas no arquivo que expus acima)). E não é só o conteúdo Javascript comprimido. Os dois arquivos que compõem o módulo biblioteca também são mesclados em um só, diminuindo assim o número de requisições necessárias. Simples assim. :)

Concluindo

Nese post apresentei uma pequena parte do projeto Jawr. Há mais neste servlet, que também pode ser usado para gerenciar recursos CSS e imagens. É importante salienar que a documentação do projeto é excelente: bem escrita e fácil de ser consultada.

Claro que a questão da modularização não termina aqui. Esta é apenas uma das soluções possíveis. Recentemente topei com um ebook online (e gratuito) chamado Writing Modular JavaScript with AMD, CommonJS & ES Harmony que trata da questão de uma forma muito mais profunda. Entra aí também o modo como escrevemos JavaScript (que não tratei neste post) e alguns outros pontos sobre os quais pretendo escrever mais a respeito em um futuro próximo.

O código fonte deste post pode ser acessado no meu GitHub: https://github.com/loboweissmann/jawr-testes

Recomendo que você leia meu último post

Repensando micro serviços (microservices)

A questão dos micro serviços ainda me acompanha. Desde a publicação do meu último post sobre o assunto venho recebendo feedback de diversas pessoas além de ter entrado em contato com tantas outras. Com a mente um pouco mais clara (ao menos espero) chegou a hora de expor minhas conclusões correntes sobre o assunto.

A grande questão: é SOA?

soa

A conclusão que cheguei é quase óbvia: sim e com poucas novidades. Alguém que me influenciou fortemente este ponto foi Steve Jones em um dos seus posts (a propósito, excelente blog). Outra fonte muito importante foi o modelo de referência SOA desenvolvido pelo OASIS em 2006 que você pode baixar aqui.

O modelo de referência do OASIS é um documento bastante árido mas que lido com atenção nos fornece um sólido conceitual para entender, de fato, o que é SOA.

O que é SOA?

Citando o modelo de referência do OASIS, SOA seria

(…) um paradigma que visa organizar e usar funcionalidades (capabilities) distribuídas que podem pertencer a distintos donos (ownership domains). Provê uma maneira uniforme de oferecer, descobrir e interagir e usar as funcionalidades visando gerar efeitos no mundo real de forma consistente com as expectativas dos consumidores e de forma mensurável.” (Reference Model for Service Oriented Architecture 1.0, linhas 863-867)

Há um conceitual muito importante (e interessante) neste documento que é importante divulgar aqui. O que é um efeito no mundo real? É o resultado do uso de um serviço por um cliente que gera a alteração no estado compartilhado entre este e seu consumidor e outras entidades que pertençam ao mesmo domínio.

Imagine um sistema de compras online: há mais de um serviço interagindo, como, por exemplo, operador de cartão de crédito, estoque, etc. Ao finalizar uma compra, o estado compartilhado por todos estes participantes será alterado: a conta do comprador terá um valor abatido e o estoque terá sua quantidade reduzida. O mundo se alterou: o estado interno do serviço não faz parte do mundo real (algo interessante para pensar hoje na hora de dormir). Este é o primeiro dos três conceitos fundamentais de SOA neste modelo de referência: efeito.

E o que é um serviço dentro deste conceitual? Segundo o modelo de referência, um serviço seria o mecanismo que permite acessar as funcionalidades (capability) que interessam o consumidor. Momento loop: o que é uma funciondalidae (capability)? É um efeito no mundo real provido por um serviço. O provedor de um serviço deve sempre oferecer duas informações aos interessados em interagir com este:

  • O modelo de dados e comportamento exposto através de sua interface.
  • A informação mínima para que o interessado em seu uso saiba que está usando o serviço certo para suas necessidades.

Estas informações são fundamentais para que o serviço possa ser descoberto. Ainda mais importante: é também interessante que o consumidor do serviço também se apresente, assim torna-se fácil descobrir quem supre a necessidade de quem. Este é o segundo dos três conceitos fundamentais de SOA neste modelo de referência: visibilidade (seção 3.2.1 do modelo de referência).

Finalmente, não faria sentido termos todos estes serviços isolados. Faz-se necessário que estes interajam de alguma maneira. No caso, pode ser tanto como troca de mensagens, como também alterando o estado de um recurso compartilhado (como um banco de dados) ou mesmo através de chamadas HTTP (REST). Para que SOA se consolide, faz-se necessário que o terceiro conceito fundamental se manifeste: interação. 

Há alguns pontos interessantes neste documento. Busque por ESB e você não encontrará menção alguma. É dito apenas que os serviços devam ser visíveis, exatamente como é dito na literatura sobre micro serviços. Outro ponto importante: vemos também que pela mensageria ou REST já teríamos uma interação bem definida. Ainda mais bacana, como no caso dos micro serviços temos um sistema no qual todos já estão por padrão no mesmo domínio, temos efeitos no mundo real o tempo inteiro.

Interessante que se você ler novamente o texto de Martin Fowler e James Lewis sobre micro serviços e logo em seguida o modelo de referência OASIS verá que o primeiro é na realidade uma vesão agradável do segundo.

Então, temos aqui SOA novamente, mas o modo de aplicação é distinto. A principal diferença que vejo é a ausência do ESB e também o fato de os serviços se conhecerem a priori. Como menciono no meu primeiro post sobre o assunto, acredito que conforme o sistema cresça um ESB ou diretório de serviços acabará surgindo novamente, o que pode acabar com o prefixo “micro”.

“Produtos, não projetos” é inviável

product

Outro ponto interessante nesta discussão sobre micro serviços é o conceito de produtos, e nao projetos. A idéia é simples: a equipe seria dividida em funcionalidades. Então eu seria responsável pelo serviço A e você pelo B, e esta seria nossa única responsabilidade. Lindo né? O problema é que não vai funcionar por um motivo bastante simples: você não quer ociosidade entre os seus funcionários.

Devemos ficar inativos enquanto não houver necessidade de alteração em nossos serviços? Ou será que na prática não iriamos simplesmente passear entre os serviços? Acredito que o passeio não é só consequencia, mas também necessidade. Ainda mais se levarmos em consideração que em equipes ágeis o conhecimento do todo se mostra fundamental.

Pode até ser viável em alguns lugares, mas acredito que seja apenas em alguns lugares ou situações nas quais os serviços terão evolução constante e contínua.

SOA pode significar várias coisas? Não.

multiplas_coisas

O artigo de Fowler e Lewis sobre micro serviços depois recebeu um box entitulado “Microservices and SOA” que não irá lhe responder se micro serviços são ou não uma forma de SOA: apenas lhe dirá que há pessoas que dizem que sim e outras que dizem o contrário. O problema é o argumento usado de que  ”SOA pode significar várias coisas”. Papo furado.

Ainda pior: se você reconhece que o público possuí dificuldade em saber a definição de algo, por que se esquivar do problema e não simplesmente buscar popularizar o real significado do termo? Dada a imensa literatura existente sobre SOA hoje apontando para o mesmo significado dizer algo assim é falso. A não ser, é claro, que você queira vender o velho como se fosse algo novo, não é mesmo?

(uma das pessoas que comentou o post de Steve Jones sobre SOA e Micro serviços aponta para o fato de que Fowler e Lewis inclusive cometeram uma falácia grave neste ponto. (esta é a falácia))

Digo mais: se quisermos ser levados a sério temos de evitar esta postura. Pouco tempo atrás mencionei um exemplo similar neste blog ao falar sobre tempo real. Indo além, se algo “significa várias coisas” é por que temos na realidade uma classificação e não um objeto disforme. Exemplo: a palavra animal pode significar várias coisas a um distraído, como coelho, cachorro, homem, etc. No entanto, sei que animal é uma classe que contém subdivisões, cada uma destas apontando para um tipo de animal diferente.

O mesmo acredito que ocorra com SOA. Há o conceito fundamental de SOA, aquele apresentado no modelo de referência que citei acima. E há as diferentes formas nas quais este é implementado, o que geraria uma subclassificação. Uma destas classificações provávelmente será a de micro serviços.

Micro serviços são uma reação

A impressão que tenho neste momento é que micro serviços são uma reação ao modo predominante que vimos SOA ser aplicado (usando ESBs). Algo muito similar ao que vimos com a popularização do REST, que era uma resposta aos webservices baseados em SOAP.

É uma maneira de implementar o SOA com menos elementos e de uma forma mais “light” removendo o ESB e tornando os micro serviços.

(perguntei ao Steve Jones se micro serviços podem ser vistos com uma reação ao SOA tradicional. A sua resposta foi bastante interessante e pode ser lida neste link)

 

SOA é para integrar sistemas e micro serviços para integrar componentes de um mesmo sistema? Não.

Em uma discussão muito interessante e rica com um colega sobre o assunto foi levantado o seguinte ponto:

“SOA não é uma arquitetura para desenvolvimento de sistemas mas sim para integração entre sistemas distintos ao contrário de micro serviços que são uma solução para o modo como interagem sistemas de uma mesma aplicação.”

Antes de mais nada é muito importante sempre nos lembrarmos o que o “A” de SOA significa: Arquitetura. Quando estou integrando diferentes sistemas estou na realidade criando e projetando um novo sistema.  A diferença é que os componentes podem não pertencer ao mesmo domínio de propriedade.

Mais que isto: é importante salientar que nem toda integração é SOA. Se integro meu site com o PagSeguro, por exemplo, será que poderia dizer estar eu implementando um SOA? E se eu defino que todos os sistemas da minha empresa irão expor uma API REST, é SOA?

Indo além: observando o modo como SOA é implantado em diversas empresas vemos que estamos na realidade criando um sistema composto por diversos outros sistemas, todos eles pertencentes a um mesmo domínio de posse, ou seja,  à uma mesma empresa. De novo, algo muito similar ao descrito na arquitetura de micro serviços hein? (de novo a mesma coisa)

Então, não: SOA não é apenas uma estratégia de integração, mas sim uma estratégia arquitetural na modelagem de sistemas. Especialmente se formos levar em questão que o analista SOA também faz a análise dos processos de negócios internos do cliente. De novo, olha o projeto de sistemas aí.

ESB é algo maligno? Não.

Em algumas discussões vi emergir a impressão de que ESBs seriam algo maligno. Discordo: o maligno é o mal uso da ferramenta. Aliás, é interessante observar que Fowler e Lewis em seu box “Microservices and SOA” terminam com uma postura nesta direção ao dizerem que “talvez micro serviços sejam SOA feito direito”, baseando-se no fato de terem vistos diversos projetos baseados em ESB fracassarem.

Eles se esqueceram de algo básico: ver uma estratégia fracassando algumas vezes não quer dizer que esta sempre irá falhar, mas sim que temos um indício de que pode ter sido mal aplicada.

Conclusões

Estes foram os principais pontos que enfrentei ao me questionar a respeito dos micro serviços. O mais importante na minha opinião é o reconhecimento de que micro serviços são na realidade uma outra estratégia na aplicação do SOA.

Acredito que pensar de forma distinta, vendo micro serviços como algo completamente distinto equivale a jogar fora anos de experiência na aplicação do SOA. Todo este conhecimento (especialmente a respeito do que não funciona) deveria ser mais valorizado na minha opinião.

Pode ser que eu mude de idéia no futuro. Isto, claro, irá depender muito das opiniões de vocês a este respeito. E você, passada esta semana, o que pensa a respeito dos micro serviços?

Aventuras de Gulliver - bom livro!

O que é arquitetura baseada em micro serviços?

Aventuras de Gulliver - bom livro!

Aventuras de Gulliver – bom livro!

O termo micro serviço tem me ocupado nos últimos meses. Vejo a Pivotal dando ênfase a este estilo arquitetural no lançamento do Spring 4,  uma apresentação interessante de James Lewis a respeito e que mais tarde, junto com  Martin Fowler irá escrever um maravilhoso artigo a respeito e até mesmo textos tolos como este. Após ter lido tantas fontes há momentos em que me sinto como Santo Agostinho ao ser questionado sobre o tempo:

“O que é, por conseguinte, o tempo? Se ninguém me perguntar, eu sei; se o quiser explicar a quem me fizer a pergunta, já não sei.” (Livro XI das Confissões de Santo Agostinho)

É interessante como na maior parte das fontes que citei o texto se inicia com algo do tipo “ainda não há uma decisão precisa do termo” (Fowler). Como verão neste post minha dúvida primária ainda se mantém: é de fato algo novo ou apenas um daqueles momentos nos quais a indústria renomeia algo que já conhecíamos e usávamos há anos apenas para nos vender alguma coisa?

Meu entendimento sobre a coisa

Resumindo: mais uma solução para o problema do alto acoplamento em aplicações corporativas. A diferença é que desta vez estamos atacando aplicações monolíticas. Bom: então primeiro é interessante pensarmos no que vêm a ser uma “aplicação monolítica”.

Uma aplicação monolítica é aquela na qual todos os componentes de negócio encontram-se dentro de uma mesma unidade de implantação. Se você é programador Java já sabe do que estou falando: os arquivos WAR ou EAR. Reparou que usei o termo “componentes de negócio”?

O que é um componente?

componenteVou usar a definição de Fowler e Lewis de componente: “é aquela unidade de software que pode ser aprimorada e substituida de forma independente”. Vamos pensar num exemplo simples: a biblioteca que você usa para compactar dados. Esta possívelmente foi feita por um terceiro. Caso este terceiro descubra uma maneira de compactar dados de forma mais eficiente, basta que você troque a biblioteca, se esta mantiver a mesma assinatura, seu sistema inteiro se beneficiará destas melhorias de forma transparente. E você apenas substituiu um pedaço do seu sistema.

Bom: qual o problema então com aplicações monolíticas? O fato destas conterem em si todos os componentes usados e todos serem executados dentro do mesmo processo. Precisou trocar um componente? Você irá fazer o deploy da unidade inteira. Já houve algumas soluções interessantes para este problema, como por exemplo o EJB e OSGi (OSGi na minha opinião é como o Java SEMPRE deveria ter sido, falo mais sobre ele no futuro).

O ideal seria que você não precisasse parar seu sistema para substituir um componente. Como no caso do bundle OSGi ou da implementação remota do EJB, mas nem sempre isto ocorre ou mesmo é necessário. Ok: você sabe o que é um componente. Um componente de negócio seria portanto aquele que encapsula um requisito funcional do seu sistema. O que é então um micro serviço? Um serviço pequeno?

O que é um serviço?

servicosSeguindo a definição de Fowler e Lewis, um serviço seria na realidade um tipo especial de componente. Aquele componente que descrevi alguns parágrafos acima é o que chamaríamos de biblioteca. É código contra o qual ligamos aquele que escrevemos, e que consequentemente nos gera um sistema monolítico. O serviço é o oposto da biblioteca, ou seja, nós não ligamos nosso código diretamente a este: apenas o executamos a partir de chamadas remotas.

Sendo assim, um serviço seria um componente executado em um processo diferente do cliente que o usa. Esta é uma idéia bastante interessante: caso um serviço apresente problemas, basta que, em tempo de execução, eu substitua apenas aquele pedaço do sistema, mantendo todo o resto em execução como se “quase nada” houvesse ocorrido. Preciso de maior escalabilidade? Poderia pensar em diversas instâncias do mesmo serviço. As possibilidades são práticamente infinitas quando pensamos desta forma.

E o que é o tal do micro serviço então?

microservicos

O prefixo “micro” é enganador. Em um primeiro momento podemos pensar que se trata de um programa bem pequeno, e na apresentação de Lewis é defendido que devem ser pequenos o suficiente para que sejam compreendidos por uma úncia pessoa.

Um micro serviço compreende um requisito funcional do seu sistema. É um componente de negócio executado em um processo externo portanto. Como requisitos funcionais podem ser complexos, nada impede que seu “micro” componente não seja tão pequeno assim (mas isto vai depender mais da sua modelagem do que desta abordagem).  Sendo assim acredito que seja mais interessante pensar que o ideal seria serem micro serviços pequenos, porém o essencial é que determinem bem o que venha a ser os requisitos funcionais que implementam.

Um sistema que siga a arquitetura baseada em micro serviços portanto é aquela que é composta por micro serviços, cada um destes responsável por um conjunto finito de requisitos funcionais do projeto.

Consequências do micro serviço

A saída do modo monolítico muda bastante coisa no nosso modo de pensar. Para começar podemos pensar em dividir melhor a equipe. Este é inclusive um ponto apresentado por Fowler e Lewis. Agora podemos ter equipes especializadas naquele conjunto de funcionalidades de negócio, que passarão a tratar o serviço não como um mero componente, mas sim um produto, com ciclo de vida independente. Isto trás implicações profundas do ponto de vista gerencial.

Outro ponto importante: como estes micro serviços se comunicam? Faz-se necessário adotar uma estratégia que facilite a integração de todas estas pontas. Em todos os artigos são expostas duas estratégias fundamentais: REST (alguns mencionam HATEOAS) e mensageria através de algum broker como ActiveMQ, RabbitMQ, HornetQ ou tantos outros. É obrigatória a presença de um protocolo aberto comum a todos os serviços: imagine ter de usar protocolos proprietários neste tipo de arquitetura, sua vida se tornaria um inferno.

Um ESB se aplica? No artigo de Fowler e Lewis ele é mencionado por alto, mas não se mostra como algo obrigatório. Sinceramente também acho que seja desnecessário, apesar de que um serviço similar ao UDDI quebre troncos nesta abordagem. UDDI é a grosso modo um diretório de web services baseados em SOAP. Algo que me responda à pergunta “qual o endereço das implementações do serviço x?” tornaria tudo muito mais fácil.

Se todos os processos são isolados, também preciso que sejam monitorados, ou seja, todo serviço deve apresentar métricas sobre sua qualidade de serviço. É fundamental que eu saiba quem está ou não online para que cada micro serviço possa implementar sua própria estratégia no caso de indisponibilidade de algum serviço do qual dependa.

E olha outro ponto importante: você também precisa de uma estratégia de versionamento que seja consistente. Se os micro serviços são por definição componentes, estes devem poder evoluir isoladamente também.

Se a comunicação entre micro serviços sempre requer a invocação de código externo é necessário pensar em estratégias visando minimizar perda de performance. Uma coisa é chamar código diretamente ligado ao meu (bibliotecas), outra código remoto.

Há também um outro ponto bastante delicado: como pensar a questão da componentização? Se quero que meus micro serviços sejam completamente independentes como organizo meu código fonte? Na apresentação de Lewis é proposto que cada equipe tenha seu próprio repositório a fim de evitar a criação de componentes compartilhados que causem dependências profundas entre um ou mais micro serviços. Faz muito sentido, especialmente se eu quiser que alguns componentes sejam escritos em linguagens distintas. Imagine dois micro serviços dependentes de uma biblioteca compartilhada: alterando-a mudo o comportamento de dois componentes que deveriam ser em teoria completamente independentes.

E estes são apenas alguns dos pontos gerais que observei nesta abordagem. Vocês com certeza me mostrarão mais alguns nos comentários deste post, certo? :)

Consequências do lado Java

Pensando como desenvolvedor Java as coisas mudam de figura no modo como pensamos o deploy de nossos projetos. Até então pensamos em arquivos WAR e EAR que iremos instalar em nossos servidores de aplicação. No entanto os serviços são executados isoladamente, certo?

Logo devemos minimizar o uso de containers. Imagine que eu sobrecarregue um container com inúmeros micro serviços. Se este cai, diversos vão junto. A solução é embarcar o container e distribuir nossa aplicação como um jar único. Já há projetos que nos permitem fazer isto. Destes o que acho mais interessante atualmente (e que podemos usar HOJE) é o Spring B oot. Grails terá algo similar em breve (afinal de contas, é Pivotal né?), Vertx também nos permite fazer algo similar.

E ei: se você olhar com atenção, verá que toda a história por trás do Node.js gira em torno deste conceito também. ;)

Mas cadê a novidade?

Este é minha grande dúvida. Cadê a novidade? Decompor nossos projetos em micro serviços é algo que fazemos há muito tempo. Veja por exemplo EJB e seu modelo distribuído. Um único protocolo comum (RMI por baixo dos panos) e lógica de negócios encapsulada no bean.

Outro exemplo interessante: OSGi. Em que eu posso inclusive fazer o deploy de um serviço (representado como um bundle) no container em tempo de execução sem parar a aplicação. Neste caso não necessáriamente seria um micro serviço pois o bundle é executado na maior parte das vezes dentro de um mesmo processo, mas poderia ser externo também.

E tem também o SOA, que nos fornece exatamente isto com o uso de ESBs, certo? Isto sem mencionar as diversas vezes em que desenvolvemos sistemas usando esta mesma abordagem no passado sem fugir muito destes princípios que apresentei sem darmos este nome (aqui está um exemplo interessante no blog do Rafael Romão).

A novidade talvez esteja no fato de finalmente estarmos dando um nome a este boi. Gosto disto, quanto melhor o vocabulário, melhor.

Concluindo

Não acredito que a pergunta “será uma arquitetura baseada em micro serviços o futuro?” será respondida somente em um futuro distante. Na realidade, ela já foi resolvida: ela é o presente. A partir do momento em que isolamos os objetivos de negócio do nosso sistema em processos isolados que possuam as características a seguir:

  • Cada serviço executado em um processo isolado.
  • Padrão de comunicação entre os serviços.
  • Pequenos o suficiente para que isolem bem requisitos funcionais do sistema.
  • Cada serviço apresente métricas sobre si mesmo.

Ou pelo menos a maior parte destes pontos, já é uma arquitetura baseada em micro serviços (ou próxima).

O que realmente gosto nesta história toda é a quantidade de discussão que imagino surgir a partir destes conceitos. Que venha e que com isto tenhamos melhores termos para estes problemas!

PS: 31/3/2014 – 11:00 AM

Encontrei uma crítica bem interessante ao texto de Lewis e Fowler que você pode ler neste link. O autor tem um ponto bastante interessante: para ele “micro serviços” são na realidade um retrocesso pois ignoram os pontos aprendidos com SOA. Os comentários são particularmente interessantes. :)

PS: 6/4/2014

Uma semana depois postei algumas conclusões a que cheguei sobre o assunto neste post.

Nike FuelBand SE: me botando pra correr

fuelbandQue me lembre esta é a primeira vez que escrevo o review de um produto neste blog. A razão pela qual faço isto é simples: desde que Nanna no dia 24/2/2014 me deu de presente uma pulseira Nike FuelBand SE minha vida mudou radicalmente. Bom: é importante contar a história do início.

Meu peso ideal gira em torno de 84 Kg. Desde que casei as coisas mudaram bastante e atualmente estou pesnado 104 Kg, o que tem me trazido alguns problemas, especialmente para o meu pé, que é chato e, apesar de sempre ter funcionado muito bem, começou a entrar em colapso devido a este meu excesso de peso. Não sou um cara esportista: detesto atividade física, odeio falar sobre esportes. Simplesmente não tenho paciência para a coisa mas como minha situação ficou muito negra passei a encarar atividade física como uma necessidade.

Personal trainer e Nike Training

Acredite: é fantástico!

Acredite: é fantástico!

Tentei diversas coisas. A primeira foi um personal trainer que me ajudou bastante mas infelizmente tive de parar pois o trabalho estava comendo todo o meu tempo. Logo em seguida comprei a única coisa útil que já vi para o Kinect: um guia de treinamentos da Nike chamado Nike Training. Não vou mentir: é incrível o negócio, meu queixo caiu e por umas duas semanas foi meu brinquedo favorito. O problema é que requer um bom espaço e no meu escritório este é bem limitado. Com isto desanimei e deixei de lado o negócio (mesmo por que a dublagem para o português me gera uma certa vergonha alheia, especialmente quando escuto “Você vai arrebentar!”).

(Li que o Kinect do XBox One consegue detectar batimentos cardíacos: se for verdade e sair um Nike Training para ele, não duvide, vou comprar um XBox One mesmo sabendo que há 90% de chance de ser outro fracasso aqui em casa)

Neste meio tempo também compramos a cota de um clube perto de casa mas este acabou deixando de ser um lugar aonde eu iria praticar esportes (natação principalmente) para se tornar um divertido boteco com piscina, o que é excelente (adoro nadar bêbado) mas fugiu do objetivo completamente (e não vamos lá já faz uns dois meses).

Entra o FuelBand SE

Ano passado vi o anúncio de lançamento da pulseira Nike FuelBand e achei fantástico. A idéia era muito boa: ela mediria todas as minhas atividades físicas durante o dia e me incentivaria a me movimentar cada vez mais. Com isto eu me exercitaria enquanto trabalho, por exemplo, sem parecer que eu esteja fazendo atividade física, minimizando a preguiça. E nestes meses que se seguiram comentei diversas vezes com a Nanna a respeito mas infelizmente não vendem ainda no Brasil este produto. Então ela me deu de surpresa uma no final de fevereiro deste ano. E não foi qualquer uma: foi o último modelo, a Nike FuelBand SE!

O funcionamento da coisa é absurdamente simples: a Nike desenvolveu uma medida para atividade física chamada Nike Fuel. São pontos que você acumula durante o dia. “Infelizmente” a explicação que a Nike dá para o modo como esta pontuação é calculada é ridícula: vou traduzir o conteúdo da página oficial para que você confira:

NikeFuel está agora melhor do que nunca. Nós melhoramos os algoritmos para que possamos medir sua atividade física com maior precisão.

Se você já usou Nike+ FuelBand no passado, pode ter a impressão de que está ganhando mais pontos ao desempenhar atividades mais intensas como jogar futebol ou correr e menos pontos para atividades menos intensas como lavar roupas ou trabalhos manuais. De qualquer maneira, independente do modo como você se move NikeFuel é uma maneira universal para medir todas as suas atividades.

Resumindo: eles simplesmente não contam como isto é medido. Talvez seja simples efeito placebo, mas sabe de uma coisa? Não ligo pois estou vendo o resultado dia após dia. Meu condicionamento físico melhora cada vez mais, não me sinto mais exausto ao subir escadas e meu sono também melhorou.

Voltando ao funcionamento, é bastante simples. Quando você tira a sua pulseira da caixa, a primeira coisa que deve fazer é instalar um programa chamado Nike+ Connect. Há versões dele para Mac e Windows. Em seguida você deve plugar sua pulseira na porta USB do seu computador.  Você irá entrar com seus dados básicos: sexo, peso, altura, etc para em seguida  definir qual a sua meta diária de NikeFuel.

Este é um ponto negativo do produto: não há um guia (pelo menos não encontrei) que te ajude a tomar esta decisão. Então peguei o valor default do software: 2500 pontos. No primeiro dia bati fácil esta meta, então aumentei para 3000 e tem sido esta a minha meta até agora.

Dia a dia com a pulseira

O seu dia a dia com ela é bastante tranquilo. Há um único botão que você usa para poder acessar suas medições diárias:

  • Fuel: quantos pontos você acumulou até aquela hora durante o dia.
  • Hours Won: quantas horas você se movimentou por mais de 5 minutos.
  • Steps: quantos passos você deu até aquele momento.
  • Cals: quantas calorias você queimou até aquela hora (pode ser bastante deprimente)
  • Time: relógio. (é o relógio mais bonito que já viu ou usei sem dúvida)

Você navega entre as métricas pressionando o botão. Se quiser ir direto para o relógio basta apertar duas vezes. Simples e direto. E o display é incrível: são pouquíssimos pontos que surgem como mágica na pulseira, é bem “coisa do futuro”.

Há um recurso muito bacana na pulseira que são as sessões. Imagine que você vai sair para uma caminhada e queira medir quantos pontos ganhou. Simples: você mantém apertado o botão por três segundos até aparecer o texto START. Pressione novamente o botão para que a sessão se inicie.  Quando terminar os seus exercícios basta pressionar o botão por três segundos para que a sessão seja finalizada.

Durante a sessão as métricas expostas mudam, e este é um ponto bem bacana:

  • FPM (Fuel per minute): quantos fuel points você está fazendo por minuto. Bacana pra verificar seu ritmo.
  • Elapsed Time: quanto tempo sua sessão durou.
  • FUEL: quantos fuel points você acumulou durante a sessão.

Como ela te incentiva

Se você ficar uma hora sem muita atividade física a pulseira começa a piscar com o seu nome um texto do tipo “GO HENRIQUE, GO!”. É a hora em que você deve se levantar da sua mesa, ir tomar uma água, conversar com os amigos, etc. Este foi o ponto que chamou o interesse pela pulseira. Sim: isto é configurável para que não fique extremamente irritante.

Outro ponto bacana é que todo dia você deve conectá-la ao seu computador. O software Nike+ Connect irá transmitir seus dados para o site NikePlus aonde é possível acompanhar todas as suas estatísticas. Há uma série de troféus que você ganha conforme progride nas suas atividades físicas. Parece tolice, mas por mais incrível que pareça (e eu estou pagando língua), é um PUTA incentivo. Você fica querendo cada vez mais, e é um pouco deprimente quando vê que não conseguiu superar a sua meta diária ou da semana.

E com isto meus hábitos foram se modificando: de repente me pego indo a pé para o trabalho diáriamente só para ganhar mais pontos. E não só ir para o trabalho, VOLTAR TAMBÉM! Um dia obtive mais de 4000 pontos (4560!) e foi uma sensação incrível. Logo em seguida me senti um idiota, mas no dia seguinte ignorei este sentimento negativo.

O lado feio

Nem tudo é perfeito. Pra começar atualmente ela só funciona com iPhones, sendo assim, se você, como eu, é usuário Android, a única maneira de sincronizar os dados com o site é via USB mesmo. E também não dá pra acompanhar pelo Android o seu desenvolvimento como no iPhone. Uma pena, mas acredito que seja temporário isto.

O site NikePlus+ também não é dos melhores. Na realidade é dos piores. O tempo inteiro você topa com mensagens como a do print abaixo:

NikePlus em manutenção?

NikePlus em manutenção?

De duas uma: ou as pessoas ficam dando manutenção o tempo inteiro ou é simples pau. Como sei disto? Simples: basta clicar no botão voltar do browser que a etapa de manutenção acaba. Recentemente tive uma experiência bastante negativa: fiquei uns três ou quatro dias sem conseguir me sincronizar com o site (e num dos dias eu havia conquistado 4700 pontos!). Solução: tive de resetar a pulseira e perdi estes dias (ódio profundo).

Se o produto vingar (e vai) acredito que este site deva melhorar bastante a estabilidade, mas por enquanto ainda é bem fraquinho. Além disto há alguns bugs também: meu avatar, por exemplo, nunca é exposto direito no site, e muitas vezes na hora de me autenticar demora horrores!

Outro ponto muito negativo é que não está a venda no Brasil ainda. Eu adoraria conhecer mais gente que usa este negócio pra poder comparar minhas métricas. Pelo site isto é possível, mas infelizmente ainda não há público aqui.

No final

A ausência de um aplicativo para Android e um site ruim são problemas menores para este produto. Se o objetivo final dele é te incentivar a ter uma vida mais ativa, pelo menos no meu caso tem funcionado perfeitamente. Acredito que no Brasil deva custar algo em torno de uns R$ 600,00. Parece caro, mas acredito que vale cada centavo (se puder importar ou ganhar de presente, melhor ainda).

PS: não consegui emagrecer ainda, pois Pizzas me rondam pela noite, especialmente quando estou escrevendo, mas já percebo algumas melhorias físicas.

Um pato? Um coelho? Ambos?

Uma proposta para melhorar o mercado de software

disquete

Alguém lembra disto?

Há dois diálogos que escuto constantemente quando o assunto é mercado de desenvolvimento de software. O primeiro se dá entre desenvolvedores ou pessoas que atuem neste mercado como fornecedores:

_ Nossa, eu fico vendo o pessoal das áreas de engenharia e medicina. O sujeito já sai da faculdade com um salário melhor que o nosso.

_ Pois é: eu saio da faculdade e tenho este salário de merda: e pra piorar não vejo como aumentar minha renda.

E por aí vai o bla bla bla todo que muitos de vocês já devem ter ouvido. Do outro lado escuto um diálogo muito interessante e comum por parte dos clientes:

_ Paguei uma fortuna por este sistema e o que tenho é esta merda.

_ Faz o seguinte então: no seu próximo fornecedor, visto que são todos iguais, ao invés de pagar uma fortuna, pegue um mais barato e fique em cima dele.

_ Pois é: mas o problema é que não entendo porra nenhuma sobre este negócio de desenvolvimento de software.

A pergunta que fica é: por que os fornecedores reclamam do baixo valor que recebem e os clientes da má qualidade do que obtém? Penso bastante a respeito e cheguei a uma idéia. Sinceramente não sei se é realmente boa mas acredito que se servir para ao menos discutirmos um pouco o assunto já terá valido à pena.

Não é regulamentar a profissão de desenvolvedor mas sim auxiliar o consumidor

Concordo com o Vinícius Godoy no que diz respeito à regulamentação da profissão do desenvolvedor (ele tem um excelente texto que pode ser lido aqui). Acredito ser esta desnecessária e nociva para o mercado. Não é regulamentar que deve imperar, mas sim o prosperar através da qualidade.

Do nosso lado, fornecedores de software, há algumas instituições interessantes como, por exemplo, a Fumsoft e a Softex que tem por objetivo fomentar o mercado através das suas iniciativas. O problema que vejo neste tipo de entidade é que seus departamentos de comunicação são péssimos. Prova disto é que pouquíssimos de nós de fato sabemos o que estas organizações fazem. Ainda pior: os consumidores não sabem de sua existência na esmagadora maioria das vezes. A impressão que fica (e não é só minha) é que são instituições voltadas do fornecedor para o fornecedor.

Não vejo nada de errado (tirando o péssimo departamento de comunicação) com estas instituições. Precisamos deste tipo de entidade.  Agora, sabe do que eu realmente sinto falta? De algo que tenha como foco o consumidor final não técnico.

O que sinto falta

Sinto falta de força em um nicho de mercado que não se preocupasse em regulamentar como fazemos software ou processos, mas que instruísse o cliente no processo de contratação do serviço de desenvolvimento de forma ativa do início ao fim. Um processo como MPS.br nos promete que temos um projeto mais previsível e que teríamos melhor qualidade dado que o fornecedor seria mais organizado internamente. No entanto de nada adianta eu ter um fornecedor organizado e brilhante se eu, enquanto cliente, simplesmente não sei lidar com este fornecedor.

Acredito que exista um nicho de mercado para os consultores que auxiliem o consumidor no processo de compra de software. Ele não verificaria o processo interno do fornecedor (temos o MPS.br para isto), mas sim ajudaria o cliente a fazer as perguntas corretas. Eis alguns exemplos:

_ Você nos apresentou sua arquitetura para um sistema de comércio eletrônico, mas não ficou claro como está sendo tratada a segurança da informação. Poderia nos clarificar isto?

_ Meu cliente precisa de um sistema de tempo real do tipo hard. Vejo que este sistema foi projetado para ser executado em uma plataforma de código gerenciado (Java ou .net). Como você garante que este requisito será satisfeito?

_ Poderia nos descrever como garantir a inviolabilidade dos dados deste sistema de controle de ponto?

Dado que uma organização governamental ou autarquia sempre é centralizadora, acredito que o ideal seria a presença de diversas empresas independentes (ou consultores) que oferecessem este serviço. Seria um mediador entre o cliente e o fornecedor, o que pode ser complicado, mas por outro lado seria também alguém que ajudaria o cliente a tomar decisões mais assertivas e com isto evitaria uma boa quantidade de retrabalho por parte da equipe de desenvolvimento também.

Claro: para clientes que já possuem know how na contratação de serviços de desenvolvimento este tipo de serviço homologador seria desnecessário, mas acredito que para setores públicos sua presença seria particularmente interessante. Bem sabemos que o processo licitatório pode não ser tão justo quanto nos dizem. Ao menos tornaria mais difícil burlá-lo. Fato é que muitas vezes (na maior parte) o cliente não sabe o que quer.

Este consultor não seria um pitaqueiro metido a besta, mas sim alguém qualificado para tal e que não fosse o defensor cego do cliente, mas aquele que também ajudasse o fornecedor. Alguns poderiam dizer: “ah, é o analista de requisitos!”. O problema é que o analista de requisitos está do lado fornecedor, e não entre os dois, portanto não seria confiável para esta tarefa. É como aquele nosso amigo que entende de carros e nos acompanha na primeira compra.

Como meu salário aumenta nesta história?

Simples: a partir do momento em que o mercado se policia (e não uma entidade policia o mercado), a pressão por qualidade aumenta. Se esta aumenta, você precisa se qualificar melhor e, consequentemente, seu valor aumenta.

Será que no caso da Medicina e Engenharia o que realmente garante bons salários é a presença de um CREA ou CRM? Ou será que não é o fato dos consumidores destes serviços possuírem a consciência de que são atividades que envolvem extremo risco?

E aí eu pergunto: será que não é hora de abandonarmos esta irresponsabilidade do mercado de software que não expõe ao consumidor final os riscos envolvidos na falha de um sistema? Um controle de estoque defeituoso pode quebrar o seu negócio (já vi um empreendimento bilionário quebrar assim).

A falta de responsabilidade do nosso setor, acredito eu, é diretamente responsável pelo tal “baixo valor pago aos profissionais”. Mudando esta impressão com certeza o valor sobe. Você se sentiria seguro sabendo que seu avião é pilotado por alguém mal pago? Se sente seguro sabendo que o software que controla sua firma é feito por alguém ainda mais mal pago?

E você? O que acha?

Como disse no início deste post, não tenho certeza se esta é uma idéia tão boa assim, mas dado que tenho me entretido com esta nos últimos meses, achei que seria interessante saber da opinião de vocês.

Um livro humano sobre segurança de software

escrevendo_codigo_seguroEstou relendo um dos melhores livros técnicos que já li: “Escrevendo Código Seguro”, de Michael Howard e David LeBlanc, traduzido aqui no Brasil pela editora Bookman e originalmente publicado pela editora Microsoft. Um livro da Microsoft, uma empresa com uma fama até alguns anos atrás tão ruim nesta área : o que poderia dar errado né? Nada: justamente pelo passado de falhas de segurança graves no Windows. Aquele velho ditado: o melhor médico é aquele que está doente.

É basicamente um livro sobre arquitetura e construção de software. Você irá encontrar técnicas que te auxiliam a escrever código menos sujeito a falhas, e também lida com questões arquiteturais muito importantes. Um aspecto histórico deste texto que o torna especial é a época em que foi escrito: foi logo após uma série de micos que a Microsoft passou envolvendo furos de segurança em seus produtos. Daquele mico a empresa criou uma iniciativa chamada “Secure Windows Initiative” (os autores fizeram parte da equipe fundadora) que realmente tornou as coisas muito melhores para usuários Windows.

Então a partir deste background dos autores podemos ter uma idéia sobre como funcionam de fato as coisas por trás da Microsoft (você sentirá vontade de trabalhar lá). O que realmente chama a atenção é o aspecto humano da coisa. O tempo inteiro os autores nos mostram como lidar com a resistência das pessoas em lidar com segurança, que muitas vezes é vista como um recurso do sistema e não o que realmente é: um elemento arquitetural que permeia cada linha de código. Então você encontrará inúmeros contra-argumentos para todas as tolices que ouvimos por aí: “depois cuidamos da segurança”, “bobagem se preocupar com isto: tem um firewall”, e por aí vai.

No que diz respeito à parte de construção você verá basicamente C++ e tecnologias que hoje não são tão usadas, como, por exemplo, ActiveX, DCOM, etc. Interessante mesmo são as boas práticas que o livro expõe de uma forma não axiomática, ou seja, é exposto em detalhes por que, por exemplo, você deve limitar a área do ataque (entender o que é isto), ter configurações seguras por padrão, etc. Há alguma coisa sobre .net, mas infelizmente não conheço muito a plataforma para te dizer se é atualizado ou não.

Atenção especial deve ser dada ao capítulo 4, em que é exposto como fazer uma modelagem de ameaças ao seu sistema. Você irá conhecer uma metodologia desenvolvida pela Microsoft chamada STRIDE que é fascinante para dizer o mínimo.

Gosto muito também do capítulo 19 em que é exposto como escrever testes de segurança. Normalmente equipes de teste simplesmente não sabem como fazer testes de segurança, então é um capítulo que, acredito, dará um diferencial para empresas que prezem de fato pela qualidade dos seus sistemas e do modo como são testados.

Na minha opinião é um livro que vai além da segurança: encontra-se no mesmo nível que o maravilhoso Code Complete que mencionei em 2009 neste blog.  É texto de formação: te torna um profissional melhor tanto técnicamente quanto socialmente. Recomendo a leitura!

PS: infelizmente não estou podendo escrever muito últimamente, o que tem me frustrado bastante, mas garanto-lhes que em breve lhes trarei algumas novidades bem interessantes sobre Groovy, Grails, Spring e “otras cositas más” que tem me animado bastante. :)