Rails acredito que seja a primeira palavra a vir à cabeça quando se fala em Ruby. A coisa é tão intensa, que não é difícil encontrar vagas e programadores entitulando-se: Rails Developer. Nem Engenheiro de Software; Nem (Back|Front)end Developer, tão pouco Ruby Developer.
Que o Rails é o framework mais conhecido dentro (e até fora) do mundo Ruby isso é um fato. Fato também é o quão simplificado o desenvolvimento utilizando ele é; Mas, já parou para pensar no trade-off existente aí?
Architecture: The Lost Years
Keynote apresentado pelo Unclebob lá no distante 2011, sobre o quão ofuscados ficamos com o Rails - e o que isso trouxe como consequência. Não é um ataque direto ao Rails, mas sim um: hey, vamos acordar pra vida e utilizar o Rails de uma forma um pouco mais decente ?
Se você nunca viu esta palestra. Pare de ler agora e veja até o final. Depois, continue lendo (pois vou assumir que você viu ao keynote)
Obviamente que ele não é o único a pensar assim. A apresentação dele gerou diversas threads na Internet sobre como fazer um aplicativo Rails desacoplado e mais sob o controle do desenvolvedor do que do framework.
Acredito que o desejo de muitos seria ter uma especie de Symfony Framework + Doctrine 2.x para Ruby. Desacoplamento. O desenvolvedor escolher as peças; ou como o Unclebob disse na palestra: acessar o diretório do projeto e pensar: "Ah, isso é um software de X; ao invés de: Aaah, isso é um app Rails."
Moldar o Rails para algo mais Domain-Driven Design
Resolvi apostar. Aposta simples, silenciosa. Aproveitei a (maior) modularidade do Rails 4 para começar a extrair algumas coisas e definir uma estrutura nova de diretórios. Preferir transparência no domínio às convenções do Rails. Movi tudo para o /domain/(modulo)/
.
- O Rails convenciona que Models devem estar dentro de
app/models
, caso contrário, o ActiveModel não funciona corretamente as relações de ORM.
Ao topar com este empecilho, não quis me alongar nisso e preferi manter todos os "Models" dentro do diretório que se é convencionado. Já viu a sopa de diretórios que isso ficou, né ? /domain
; /app/models
.
- O ActiveRecord possui features intrigantes, como por exemplo os scopes, porém os Contras são maiores do que os Prós.
O Avdi Grimm no livro Objects on Rails mostrou passo a passo como ele construiu um software Rails-based postergando relacionar suas entities ao ActiveRecord. No final, ele preciso modificar bastante coisa para tê-las in place. Alguns testes precisarão ser de integração (scopes, olho para vocês) - pois teste de Unidade Comportamental (Unit-Testing Behavioral) não garantirá que o scope está correto mesmo.
Pode parecer xiitismo, mas o ActiveRecord é pesado. E esse peso aparece ao rodar os testes de unidade. Mesmo utilizando Test Double, só de precisar subir toda aquele estrutura do ActiveRecord, o processamento já fica mais lento do que se as entidades fossem livres do meio de persistência.
- Convention Over Configuration em um framework Arquitetural (One Size Fits All) é nocivo para adotar meios e métodos alternativos.
Seguir o caminho sem o Rails
Optar por deixar o Rails de lado, utilizando somente o que você precisa e quando precisa é uma das alternativas dos Rubistas (outside Brasil) atualmente. Isso explica a popularidade que o Sinatra ganhou nos últimos tempos. Sinatra pois ele fornece uma interface simples entre o Rack e sua aplicação web. Sinatra, pois ele é somente isso, deixando todas as demais decisões para você. Com isto em mente, vale lembrar de que precisará criar suas próprias coisas.
Algumas muito simples outras nem tanto:
- Criar e configurar seu
config.ru
para que o Rack o leia e suba um stack; - Configurar seu
spec_helper.rb
outest_helper.rb
para Unit Testing com RSpec ou MiniTest; - Criar seu Environment Manager, para conseguir distinguir Development, Testing e Production modes - Dica:
ENV['RACK_ENV']
pode ser usado pra isto; - Configurar seu
Rakefile
para manipular Rake Tasks; - Definir um Autoloader para ler sua estrutura de diretórios.
/domain
e/controllers
, como é o meu, por exemplo. - Migration, Validation, ORM, etc.
Particularmente quando fiz isso pela primeira vez me senti perdido. Não é cuspindo no prato não, mas o Rails o faz criar manias e uma certa dependência nele.
Importante resaltar que você não precisará das coisas da mesma forma que o Rails criou. A vantagem é que você cria as coisas on demand, voltadas às suas necessidades. Por exemplo, meu Environment Manager é muito mais simples do que o do Rails, entretanto, consigo com ele diferenciar os Envs e subir coisas diferentes.
Outra vantagem é que construo um stack muito simples, rápido e customizado. Precisei apenas de 2 dias para ter um sandbox com Sinatra funcionando e meus testes de unidade com RSpec ficam na casa dos 0.00xx sec.
O tempo "gasto" estudando como fazer certas coisas vale muito a pena, pois você entende melhor como funciona a arquitetura por debaixo do Rack. Você no controle!
Desta forma, até agora não poluí meu código com ORM, Validations, etc. Quando realmente preciso de alguma coisa, vou lá e pontualmente a configuro/instalo.
Próximos steps: Virtus gem para Entity Modeling; ActiveModel::Validations ou o ActiveValidators; Sequel ou Rom-rb; Asset Pipeline - Sim, nada me impede de utilizá-lo standalone numa arquitetura onde eu consigo ter o controle ;)
Aos poucos pretendo ir comentando minhas aventuras nessa área. O resultado tem sido bem satisfatório até o momento. Recomendo tentar você também!
Concluíndo
Não me entenda errado: o Rails possui seus pontos positivos. Particularmente, gosto do Asset Pipeline e dos Validators (externos à classe, não aqueles validates :field
). O propósito aqui é fazer o que muitos developers lá fora já fazem: abrir o olho da comunidade de que há um mundo imenso fora do Rails e que você precisa pensar: eu preciso do Rails ou estou apenas com medo/preguiça de seguir outra solução?
1 - Foto da arquitetura da Ponte de Londres.
0sem comentários ainda