Porque essa é uma das melhores alternativas ao Ruby on Rails
Set 8 | Henrique F. TeixeiraSe você é dev Ruby, está pensando em desenvolver um projeto novo e buscando alternativas ao Rails, seja por questões de performance ou arquitetura, considere o framework Roda.
Roda foi criado por Jeremy Evans, core commiter do Ruby e um dos desenvolvedores mais influentes da comunidade, e na minha opinião, o framework é o mais bem escrito considerando as características da linguagem: ele consegue tirar vantagem da sintaxe e metaprogramação de forma inteligente e simples ao mesmo tempo que traz extrema produtividade, extensibilidade e alta performance.
Através desse artigo te explico o porquê.
Performance
Quando Ruby foi criada por Yukihiro Matsumoto (conhecido como "Matz") em 1993, o objetivo principal não era desempenho máximo, mas sim tornar o desenvolvimento de software mais agradável e eficiente, e isso se traduz em:
- Sintaxe expressiva e legível.
- Menos código para resolver problemas.
- Preferência por produtividade e manutenibilidade em vez de performance bruta.
Hoje, mais de 30 anos depois, podemos dizer que o Matz atingiu (e continua atingindo) seu objetivo, com uma adoção muito forte entre startups de alto crescimento, especialmente através de Ruby on Rails.
Porém, em troca desses benefícios, a linguagem traz algumas limitações importantes:
-
CPU: Ruby é uma linguagem interpretada e altamente dinâmica. Métodos podem ser redefinidos em tempo de execução, classes podem ser alteradas a qualquer momento e a resolução de chamadas acontece de forma mais complexa do que em linguagens estaticamente compiladas. O JIT do Ruby moderno (YJIT) melhorou bastante o cenário, mas Ruby ainda costuma ser significativamente mais lento em tarefas intensivas de CPU.
-
Garbage Collector: Ruby utiliza um GC (Garbage Collector) geracional e incremental relativamente avançado, mas ainda existem pausas de coleta que podem impactar a latência. Aplicações com muitas alocações de objetos podem passar uma parcela considerável do tempo executando o GC em vez da lógica de negócio.
-
Fragmentação de memória: Mesmo após o GC liberar objetos, o processo Ruby nem sempre devolve essa memória ao sistema operacional de forma eficiente. Em aplicações que executam por longos períodos, é comum observar crescimento gradual do consumo de memória.
De forma resumida, um sistema escrito em Ruby com muitas abstrações, objetos alocados e metaprogração pode acabar custando mais caro e exigindo mais hardware.
Tendo isso em vista, vamos comparar alguns frameworks. Utilizei a classe ObjectSpace para identificar quantos objetos temos criados em uma aplicação web Ruby, comparando Rails (modo "minimal"), Hanami e Roda criada com roda-project (a forma mais rápida de criar uma aplicação Roda fullstack com diversos plugins habilitados). Isso significa que comparei 3 ferramentas que incluem funcionalidades equivalentes, não somente um sistema de roteamento, e ainda dei vantagem para o Rails utilizando seu modo mais "leve".
Para ambas as aplicações, adicionei uma rota /home/index e uma view com o seguinte código:
<% @objects = ObjectSpace.count_objects %>
Total (slots): <%= @objects[:TOTAL] %>
Free (free slots): <%= @objects[:FREE] %>
Objects (active objects): <%= @objects[:T_OBJECT] %>
Para tornar os testes um pouco mais reais, também enviei uma carga alta de requisições para os endpoints utilizando o Apache Benchmark (ab) e para ambos utilizei o Puma com 1 worker e 3 threads.
Esses foram os resultados:
- Rails (minimal): Total: 409268, Free: 47989, Objects: 25264
- Hanami: Total: 346016, Free: 47648, Objects: 10682
- Roda (com roda-project): Total: 239621, Free: 14515, Objects: 7661
Em memória (verificado com top -p), esses objetos alocados representaram:
- Rails (minimal): 222MB
- Hanami: 139MB
- Roda (com roda-project): 136MB
E aqui a quantidade de requisições por segundo:
- Roda (com roda-project): 939.89rqs
- Hanami: 376.38rqs
- Rails (minimal): 242.81rqs
Com uma lógica simples, podemos traduzir os resultados dos benchmarks para dinheiro gasto: Imagine que temos a mesma aplicação do benchmark rodando para diversos usuários e atualmente gastamos $3000 com servidores utilizando Ruby on Rails. Gastaríamos aproximadamente $1937 se estivessemos utilizando Hanami, e somente $775 utilizando Roda. Claro que é um exemplo simplório e hipotético, a performance pode variar drásticamente dependendo do código que escrevemos e o problema que estamos resolvendo. Além disso, o banco de dados geralmente costuma ser o maior ofensor de performance em aplicações web.
Mas não podemos negar um fato, Roda é o framework que entrega mais com menos quando o assunto é memória e performance, e muito se deve a sua arquitetura e sistema de roteamento:
- A avaliação da requisição para no exato momento em que o caminho (path) encontra seu bloco correspondente.
- O uso de cache em estruturas internas garante um overhead mínimo (Templates pré-compilados, tabelas de lookup para rotas estáticas, app freezing).
- Sem meta-programação pesada: Muitos frameworks usam
method_missingou definem métodos dinamicamente durante o tempo de execução, o que piora a performance.
Veja também os benchmarks do techempower.com, onde Roda aparece constamentemente entre os frameworks melhor rankeados do ecossistema Ruby
Plugins / Extensibilidade
Roda foi projetado em torno de um sistema de plugins extremamente simples e previsível.
Diferentemente de outros frameworks que expõem dezenas de pontos de extensão espalhados por callbacks, middlewares, generators e convenções, o Roda concentra praticamente toda sua extensibilidade em plugins que modificam a classe da aplicação de forma explícita.
Quando escrevemos:
class App < Roda
plugin :render
plugin :json
plugin :all_verbs
end
Cada plugin adiciona métodos, comportamento ou recursos diretamente à aplicação. Não existe mágica escondida. Você consegue rastrear exatamente de onde cada funcionalidade veio
Outro aspecto importante é que o núcleo do Roda é extremamente pequeno. O roteamento, que é a principal responsabilidade do framework, permanece separado de recursos adicionais. Isso permite que funcionalidades como renderização, autenticação, sessões, cache, CSRF, JSON e demais sejam implementadas como plugins independentes, sem aumentar a complexidade do core, permitindo também que nossa aplicação não desperdice recursos em funcionalidades que não iremos utilizar.
Por fim, o sistema de plugins do Roda é utilizado pelo próprio framework. Muitos recursos considerados "nativos" são implementados exatamente da mesma forma que plugins criados por usuários. Isso é um sinal de uma arquitetura extensível: os mecanismos usados internamente são os mesmos disponíveis para quem desenvolve aplicações.
Veja como é simples criar plugins para o Roda seguindo os passos descritos no repositório: github.com/jeremyevans/roda#label-Plugins
Produtividade
Apesar de ser um framework aparentemente "pequeno", ao analizarmos a quantidade de plugins nativos e plugins disponibilizados pela comunidade, temos recursos disponíveis para torná-lo similar ao Rails em features e desenvolver qualquer tipo de aplicação.
Existem mais de 100 plugins oficiais listados na documentação oficial, alguns essenciais como:
- CSRF
- Sessions e Cookies
- I18n
- Views / Renderização
- Hooks
- Logs
- Envio de email
Além disso, das alternativas ao Rails, Roda é o único framework que conta com uma gem de autenticação própria e robusta. A gem rodauth adiciona um sistema de autenticação extremamente completo e seguro na nossa app, contendo diversos recursos, como:
- Gerenciamento de contas
- Recuperação de senha
- JWT
- SMS codes / Recovery codes
- Passwordless Authentication
E para facilitar a criação e desenvolvimento de novas aplicações, temos a gem roda-project, que fornece um scaffold moderno para aplicações Roda, incluindo generators e várias tasks essenciais, tornando a experiência de desenvolvimento próxima ao Rails.
Não podemos deixar de falar que todo o ecossistema de gems do Ruby está a nosso dispor para o que precisarmos, incluindo sidekiq, dry-rb, rom, async e etc…
Maturidade
Roda existe há mais de 10 anos e tem mais de 20 milhões de downloads. O framework é uma escolha consolidada para empresas que já utilizam Ruby e querem extrair a máxima performance com baixo consumo de memória. Atualmente existem grandes projetos utilizando o framework em produção, com destaque para a Ubicloud. Além disso, o trabalho de Jeremy Evans é notório por sua política de tolerância zero a bugs e respostas rápidas no GitHub. Correções de falhas e implementações de segurança costumam receber atualizações (releases) em prazos extremamente curtos, garantindo uma base de código confiável.
Conclusão
Por muito tempo, a comunidade conviveu a premissa de que a agilidade de desenvolvimento no ecossistema Ruby exigia um sacrifício inevitável: alto consumo de infraestrutura, processos pesados e muita "mágica" nos bastidores. O Roda desconstrói essa ideia por completo, representando uma mudança de paradigma e unindo o que antes parecia impossível no mundo Ruby: a expressividade e a produtividade que amamos, com uma economia real de servidores e uma performance de alto nível.
Se o Rails foi a ferramenta que popularizou o Ruby permitindo criar negócios de forma rápida, o Roda é a resposta madura para a engenharia de software moderna, e quando falo engenharia, não quero dizer "camadas e camadas" de abstrações, falo sobre resolver problemas com as ferramentas certas, de forma inteligente, selecionando e utilizando apenas o necessário, mantendo a simplicidade e manutenabilidade (sem "overengineering" ou "underengineering").
Ei, o que achou desse artigo??Compartilhe e dê sua opinião clicando em uma das redes abaixo:
Muito obrigado!
