Usando azk no ciclo de desenvolvimento de uma aplicação já existente

Às vezes, você só precisa de algo que alguém já pensou e fez bem-feito… e continuar a partir dali

To read the English version, click here.

Em nosso artigo anterior, demonstramos como usar o azk para instalar
Ruby on Rails do zero na sua máquina e levantar um novo ambiente de desenvolvimento (com banco de dados) para começar uma nova aplicação.

Tudo isso em apenas 10 minutos!

Legal, não? . ;)

Instalar e configurar ambientes de desenvolvimento ainda é uma tarefa trabalhosa… manual, longa, repetitiva e propensa a erros. Mostramos como o azk tira esse processo da era medieval sem muito esforço.

Produtividade e controle de qualidade.

Em nossa experiência fazendo apresentações em eventos técnicos ou em empresas de todos os portes, sempre ouvimos as mesmas duas perguntas da audiência no final. Uma delas é: "então é só isso que o azk faz?"

Não, o azk não faz "só" isso.

O azk é para todo o ciclo de desenvolvimento.

Neste post, demonstraremos como usar o azk durante o desenvolvimento de uma aplicação ao longo de algumas iterações. Aproveitaremos a oportunidade para fazer isso em uma aplicação já existente.

Afinal, o azk não é "só" para novas aplicações que já comecem com ele.

Para isso, usaremos o Selfstarter, uma aplicação open source muito popular para a criação de sites de campanhas de crowdfunding fora de plataformas como o Kickstarter ou o Broota.

Como o Selfstarter é uma aplicação Rails, as iterações que faremos serão típicas de um projeto deste tipo:

  • adicionar uma gem;
  • criar uma migração;
  • adicionar um microsserviço.

Executaremos esses passos em um ambiente completamente isolado (fazendo uso extensivo de Docker, mas você nem vai notar), com alta performance da aplicação executada e com reduções importante de complexidade.

O projeto Selfstarter

Após ter seu projeto rejeitado no Kickstarter, o time da Lockitron resolveu criar seu próprio site de crowdfunding para financiar a idéia (que bateu a meta de US$ 150.000,00 em 24h!). Daí, surgiu o Selfstarter: um boilerplate open source escrito com Ruby on Rails para criação de sites para crowdfunding.

Seu funcionamento é bastante simples: um arquivo de configuração (config/settings.yml) guarda as informações do projeto (nome do projeto, vídeo de apresentação, valor pleiteado etc.) e o banco de dados armazena outras informações como os usuários que doaram, os pagamentos realizados e os benefícios que cada usuário receberá para sua faixa de valor doado caso o projeto arrecade o valor esperado.

Por padrão, o projeto usa Amazon Payments para receber as doações.

Partindo do estado atual do projeto, vamos mostrar como usar o azk para adicionar duas novas funcionalidades:

  • autenticação de usuários;
  • captura de e-mails para depuração.

O projeto final, contendo a integração com o azk e as novas funcionalidades, já está disponível neste repositório do Github.

Instalando o azk

Se você ainda não tem o azk instalado, basta seguir a documentação oficial. É muito simples e rápido.

Primeiros passos: setup do Selfstarter

Com o azk instalado, o primeiro passo é iniciar o azk agent:

$ azk agent start

Em seguida, vamos clonar o repositório do Selfstarter (lembre-se de verificar se o diretório atual é o mesmo onde deseja armazenar o projeto):

$ git clone https://github.com/lockitron/selfstarter.git
$ cd selfstarter

Por padrão, o Selfstarter utiliza o SQLite como banco de dados no ambiente de desenvolvimento. Como o azk permite que mudanças arquiteturais sejam feitas com facilidade, vamos alterar o banco para o PostgreSQL no lugar do SQLite.

Para isso, remova a gem `sqlite3` e adicione a gem `pg` ao grupo development do Gemfile do projeto (clique aqui para ver o Gemfile desta etapa):

Feito isso, vamos usar o comando abaixo para deixar o azk sugerir um Azkfile.js para o projeto.

$ azk init

O arquivo Azkfile.js é um arquivo manifesto que descreve o sistema do ponto de vista de arquitetura funcional e a espinha dorsal da experiência de uso do azk.

Para saber mais, consulte nossa documentação.

A geração automática do Azkfile.js ainda não é um processo perfeito, mas ele chega perto (e estamos trabalhando na sua melhoria). Por outro lado, é muito fácil fazer as edições finais necessárias no arquivo.

No nosso caso, primeiro é necessário fazer algumas modificações no system `selfstarter`. O azk sugere a última versão de Ruby disponível no repositório de imagens (Ruby 2.2.2), mas o Gemfile especifica Ruby 2.0.0. Além disso, vamos alterar os passos de provision (comandos que são executados pelo azk antes de subir a aplicação).

Para ver a versão do Azkfile.js desta etapa, clique aqui.

Para que o Rails se conecte ao PostgreSQL, é preciso utilizar o arquivo config/database.yml apropriado, que seja capaz de interpretar as variáveis de ambiente exportadas pelo azk e transformá-las no formato YAML padrão do Rails.

Não é nada demais, porém, para sua comodidade, já criamos este arquivo com suporte à variável “DATABASE_URL”, que o azk vai injetar no ambiente da aplicação durante o processo de inicialização:

$ mv config/database.yml config/database.default.yml
$ azk shell -c “curl -L http://bit.ly/1Nkuqnk -o config/database.yml”

Pronto! Agora já temos o ambiente configurado para rodar o Selfstarter tal como ele é originalmente. Para iniciar a aplicação e vermos o resultado, basta executar:

$ azk start -o
Os projetos executados localmente com o azk sempre têm resolução local de DNS para evitar o inferno de "localhost:XYZ"

Interação 1: adicionando autenticação

O Devise é uma gem popular e de uso prático para a adição de autenticação em aplicações Rails.

Adicionar o Devise ao Selfstarter utilizando o azk é trivial. Primeiro, vamos adicioná-lo ao Gemfile (clique aqui para ver o Gemfile desta etapa):

Em seguida, rodaremos o comando `bundle install` para de fato instalarmos a gem e, por fim, executaremos os generators do Devise. Tudo isso deve acontecer no contexto da aplicação Rails, que pode ser acessada pelo comando `azk shell`:

$ azk shell
# bundle install
# bundle exec rails generate devise:install
# bundle exec rails generate devise User
# exit
Caso você esteja usando Linux, é preciso transferir a propriedade dos arquivos gerados para o usuário atual. Os arquivos do Devise são gerados de dentro do contexto do Rails, que roda com usuário root. Caso a configuração `usuário_atual:grupo_principal` não seja sua opção, modifique o comando abaixo como for mais adequado:
$ sudo chown -R `id -un`:`id -gn` .
Foi mal por isso. É uma limitação do próprio engine de containers do Docker.

O Devise cria um arquivo de configuração (config/initializers/devise.rb), que deve ser ajustado. As modificações são:

  • Descomentar a linha que contém a propriedade config.secret_key;
  • Definir o remetente dos e-mails enviados por meio da propriedade config.mailer_sender;
  • Reduzir o tamanho mínimo das senhas dos usuários para 6 caracteres;
  • Definir que o método de sign out deverá acontecer por meio de uma requisição GET;

Para ver esse arquivo desta etapa do processo, clique aqui.

O Devise também gera uma migração para criar, se necessário, a tabela de usuários (users) ou para adicionar os campos que faltem a ela. Como o projeto original já possui uma tabela de usuários que possui uma coluna de e-mail, devemos modificar a migração do Devise para evitar esse conflito, removendo a linha abaixo (clique aqui para ver o arquivo de migração):

Em seguida, vamos fazer com que o usuário esteja autenticado para que ele possa ir para a página de preorder. Para isso, modificaremos o controller correspondente (clique aqui para ver o app/controllers/preorder_controller.rb desta etapa):

Por fim, vamos gerar as views do Devise, que serão modificadas mais adiante para deixar as páginas de cadastro e log in com o mesmo layout do restante do projeto:

$ azk shell -c “bundle exec rails g devise:views”
$ sudo chown -R `id -un`:`id -gn` .

Com isso, já temos processos simples de cadastro e log in usando o Devise. Para testar, vamos reiniciar o azk, informando que ele deve executar os passos de provision novamente (flag -R):

$ azk restart -Ro

Daí, ao clicarmos no botão Reserve Now da página inicial, devemos ser encaminhados para a página de login do Devise. Done!

Melhorias no layout das páginas de autenticação

Como é possível notar, as páginas geradas pelo Devise possuem um layout bem simples. Para deixá-las com uma cara mais parecida com o padrão do Selfstarter, fizemos algumas melhorias:

  • Melhorar layout das páginas geradas pelo Devise (log in, cadastro, “Esqueci minha senha” etc.) (ver commit);
  • Adicionar links no header para Log out e Editar perfil (caso o usuário esteja autenticado no sistema) ou Log in e Cadastrar (caso contrário) (ver commit);
  • Como a página de preorder só será acessível para usuários cadastrados, o campo de e-mail já pode ser previamente preenchido com o e-mail do usuário (ver commit);

Para não inundarmos este artigo com código demais, recomendamos que você veja os commits de cada alteração no GitHub e baixe de lá mesmo os arquivos necessários.

Adicionando o serviço de captura de e-mails

Assim como muitos sistemas de autenticação, o Devise interage com o usuário principalmente via e-mail. São muitas as finalidades, tais como: novo cadastro, “Esqueci minha senha”, e-mail de confirmação de conta etc.

Testar o envio de e-mails é uma dificuldade muito comum no desenvolvimento de aplicações web. Existem diversos workarounds: colocar um serviço de e-mail real, confiar nos logs etc.

O Mailcatcher é uma ferramenta open source que oferece uma solução elegante para esse problema. Ele simula um servidor de e-mails SMTP e exibe em uma interface web todos os pedidos de envio de e-mail que ele recebe.

Antes de testarmos os e-mails enviados pelo Devise, adicionaremos o Mailcatcher ao nosso ambiente. Para isso, basta alterar o Azkfile.js do projeto (clique aqui para ver o Azkfile.js desta etapa):

Para configurarmos o Rails para usar o Mailcatcher no ambiente de desenvolvimento, devemos adicionar as seguintes configurações ao fim do arquivo config/environments/development.rb (clique aqui para ver o arquivo desta etapa do processo):

Agora o azk será capaz de subir o serviço Mailcatcher. E o Rails será capaz de se conectar a ele. Para testar, basta reiniciar o azk:

$ azk restart -o

Ao escolhermos a opção de recuperar a senha para um usuário previamente cadastrado (“Forgot your password?” na tela de log in), um e-mail deve ser enviado e poderá ser acessado pela interface do Mailcatcher (o comando de restart do azk deverá informar a URL local do Mailcatcher, como por exemplo http://mail.azkdemo.dev.azk.io/)

Enviando e-mail de confirmação para novos usuários

Uma das possibilidades que o Devise nos dá é a de pedir que o usuário confirme seu e-mail antes de liberarmos a ele o acesso ao nosso site. Essa opção é chamada de confirmable.

Para adicionar a opção confirmable aos usuários do Selfstarter, e assim também podermos testar o Mailcatcher mais facilmente, devemos criar uma migração que contemple as colunas utilizadas pelo Devise. Para isso, devemos executar o seguinte comando (que rodará no contexto do Rails):

$ azk shell -c “bundle exec rails generate migration AddConfirmableToUsers confirmation_token:string confirmed_at:datetime confirmation_sent_at:datetime unconfirmed_email:string”

Em seguida, devemos alterar o modelo do User (app/models/user.rb) adicionando a opção confirmable (clique aqui para ver o arquivo desta etapa do processo):

Pronto! Agora é só reiniciar o azk (com a flag de reprovisionamento ativada) e o Selfstarter estará com sistema de autenticação, captura de e-mails e confirmação dos e-mails dos usuários.

$ azk restart -Ro

O azk no dia-a-dia do desenvolvedor

"Ao infinito e além!"

Com esse exemplo bem simples, procuramos demonstrar que o azk é um grande aliado no dia-a-dia do desenvolvedor.

O azk não é "só" para facilitar o setup do projeto.

O azk nos entrega uma arquitetura imutável, que nos permite destruir o ambiente inteiro e construí-lo novamente (instantaneamente!) até o ponto mais recente sempre que for preciso.

Isso significa uma enorme economia de tempo e de esforço para o desenvolvedor, pois o código se torna mais confiável e robusto. O código não funciona apenas devido às condições atuais do ambiente.

Ou seja, sem mais daquela de “Works on my machine!".

Conforme o projeto cresce e fica cada vez mais complexo, esse tipo de garantia se torna um benefício ainda mais concreto.

Podemos fazer uma analogia direta disso com o uso de testes: se começarmos a escrever o projeto com testes desde o início, a complexidade do desenvolvimento não escalará quando ele se tornar maior e mais complicado porque a base estará assegurada.

No exemplo com o Selfstarter, mostramos que é possível fazer todas as operações comuns a um projeto Rails (adicionar uma gem, criar uma migração, adicionar um microsserviço) usando o azk em um contexto totalmente isolado (eu nem tenho Rails instalado na minha máquina!) e sem deixar o processo mais lento ou complicado.

A propósito, você notou que usamos Docker o tempo todo? Eu aposto que não, certo?

Ainda assim, nossa aplicação final é 100% "dockerizada". ;)

O azk também cuida disso pra você.

Mas enfim, com o azk nos entregando uma arquitetura imutável do sistema, podemos nos sentir mais seguros e confiantes para dar passos mais ousados no desenvolvimento e na elaboração da arquitetura da aplicação.

Vamos arrojar então! ;)
Time Azuki

PS: a segunda pergunta que sempre ouvimos da audiência ao fim de todas as nossas apresentações e sua resposta ficam para um próximo post… em breve!

Mais sobre o azk

+ Site: http://azk.io
+ Github: https://github.com/azukiapp/azk
+ Documentação: http://docs.azk.io
+ Diretório de imagens criadas pelo time do azk: http://images.azk.io

Contribua com o azk

+ “Star” o azk no Github: https://github.com/azukiapp/azk
+ Reporte um problema: https://github.com/azukiapp/azk/issues/new
+ Ajude a resolver um problema reportado: https://github.com/azukiapp/azk/issues
+ Confira os sponsors do azk: http://azk.io/#sponsors

Fale com o time do azk

+ Assine a newsletter semanal: http://www.azk.io/#newsletter
+ Acompanhe o blog: https://medium.com/azuki-news
+ Fale com nosso suporte(chat): https://gitter.im/azukiapp/azk/pt (Português) e https://gitter.im/azukiapp/azk (English)
+ Facebook: https://www.facebook.com/azukiapp
+ Twitter: http://twitter.com/azukiapp
+ YouTube: https://www.youtube.com/user/Azukiapp/videos