Posted on: August 05, 2021 11:28 PM
Posted by: Renato
Views: 475
Laravel ou Lumen? Qual escolher?
“Eu tinha que fazer a pesquisa de qualquer forma (por motivos de trabalho), então porque não divulgar os resultados?”. Além do mais, faz algum tempo que penso em começar a escrever, mas nunca parei e dediquei o tempo necessário. Esse estudo me pareceu uma ótima oportunidade de resolver isso.
Eu sempre me perguntei qual a real diferença entre esses dois irmãos (Lumen e Laravel), e se realmente vale a pena desistir de algumas vantagens que apenas o irmão maior (Laravel) entrega, para ganhar uma melhoria na velocidade da aplicação com o irmão menor (Lumen). Fica claro que para tomar essa decisão, a grande pergunta é “quanta velocidade estou ganhando”? O objetivo aqui não é entregar uma verdade absoluta, mas trazer alguns dados experimentais para a discussão, de forma que o leitor possa julgar e tirar suas próprias conclusões. É claro que simplesmente não há respostas absolutas aqui, sendo que a decisão final é completamente dependente de cada projeto.
Primeiramente, vamos deixar claro o que estamos comparando. Se você está construindo um website/sistema que renderiza páginas diretamente usando templates, e mantém o estado por meio de sessões, não há discussão: Você só pode usar Laravel (dadas as duas opções). Simplesmente porque o Lumen não dá suporte a nada disso. O Lumen foi concebido para suportar stateless APIs (o Laravel também suporta stateless APIs). Então estamos comparando apenas o que os dois frameworks podem atender (stateless APIs).
Antes de começar qualquer comparação, vamos definir rapidamente as principais diferenças entre os dois frameworks, comentar brevemente cada uma (vantagens e desvantagens) e no final, munido de resultados medidos em uma bateria de benchmarks, comparar as performances.
Diferença 1 — View templating
Esta é a diferença mais conhecida e comentada. O Laravel usa o Blade para suportar templates (e o Blade é uma ferramente muito boa!), já o Lumen simplesmente não suporta templates.
Eu não estou considerando essa diferença na comparação, porque, conforme já disse, estamos usando o Laravel para entregar uma API stateless, então templates simplesmente não fazem sentido aqui. Claro que o Blade estará lá, mas nós não vamos nem carregá-lo na aplicação.
DIferença 2 —Sessões
O Lumen não tem nenhum mecanismo para gerenciar sessões, por ser desenhado para trabalhar sem nenhum armazenamento de estado (stateless). Já o Laravel tem um sub-sistema de gerenciamento de sessões poderoso.
Novamente não é um problema considerável, já que estamos construindo uma API (que por definição é stateless), então o motor de sessões do Laravel será totalmetne desabilitado (da mesma forma que acontece com as views/templates).
Diferença 3 — Roteamento
Agora sim! Temos uma diferença considerável! O sub-sistema de roteamento do Laravel é muito poderoso. Entre outras coisas, permite você criar rotas resource (que englobam todas as rotas CRUD de um recurso em uma só), e automaticamente carrega objectos Eloquent baseado em valores passados na requisição (esse mecanismo também toma conta de retornar o erro corretamente quando um recurso não é encontrado). Isso permite que o código dentro dos controllers fique limpo e elegante. O código de definição das rotas em si é muito elegante. O roteador do Laravel também suporta caching, o que melhora consideravelmente a performance do mesmo quando o cache está ativo. Claro que todo esse poder tem seu preço. O roteador do Laravel (ainda que com o cache ativo e renovado) não é nenhum ás da velocidade. Por esse motivo que o Lumen foi empacotado com um roteador opensource terceiro, muito mais simples porém mais rápido. O roteador do Lumen não dá suporte a carregamento automático de objetos Eloquent (o que para mim é a maior desvantagem), nem suporta cache (o que não é grande coisa já que ele é mais rápido). Nem vou cometar sobre a “elegância” do código de um ou de outro, pois isso é apenas visual.
A pergunta aqui é: Estamos dispostos a abandonar uma funcionalidade interessante (como carregamento automático de objetos Eloquent) em troca de velocidade? Sendo assim, precisamos saber se o ganho de velocidade justifica a perda de agilidade no desenvolvimento. Mas isso é assunto para a parte de benchmarks.
Diferença 4 — Form Request
Form requests são estruturas usadas pelo Laravel para representar o corpo de uma requisição, encapsulando a lógica de validação da requisição. Inicialmente o objetivo era representar formulários HTML (daí o nome form request), mas na prática essa estrutura pode (e deve!) ser utilizada para qualquer requisição (inclusive o corpo de requisições REST, como POST , PUT e PATCH). Essas estruturas cuidam de toda a validação de entrada na aplicação, tratando e respondendo com os erros de validação corretamente formatados quando a validação falha (incluindo o código de erro HTTP). Tudo isso antes mesmo de atingir o controller. Tudo que você precisa fazer é o type-hint no parâmetro request da função do controller. Além disso, apesar do Laravel não possuir nenhuma estrutura para sanitização de dados de entrada, é muito simples de estender a funcionalidade dos form requests para prover sanitização utilizando código de terceiros. O interessante é poder confiar que toda requisição que chega ao seu controller é válida, e você não precisa “sujar” seu controller com lógica de validação. Isso ajuda , e muito, na leitura do código posteriormente.
O Lumen não suporta form requests, e isso se deve muito a diferença de roteadores comentada acima (seu roteador simplista não consegue carregar atuomaticamente um objeto de form request). Neste caso não tem jeito, qualquer validação ou sanitização de entrada precisa ser escrita dentro do controller.
Diferença 5 — Eloquent
Ambos os frameworks suportam o Eloquent (motor de mapeamento objeto-relacional do Laravel — ORM), mas apenas no Lumen você consegue desabilitá-lo totalmente (inclusive ele vem desabilitado por padrão).
Aqui temos uma discussão difícil. Quando se fala em MVC, é um assunto fortemente relacionado (quase inseparável). Em geral, quando você usa um framework MVC, você espera encontrar suporte a ORM, porque ele é o principal responsável pela agilidade de desenvolvimento que um framwork entrega. É claro que enviar SQL direamente para o banco de dados é mais rápido que usar ORM. Mas você realmente quer cuidar de todos os relacionamentos manualmente? Cuidar das transformações de tipos (datas, timestamps, arrays armazenados em campos json)? Você quer assumir a responsabilidade dos riscos que isso carrega? Pense na manutenção!
O fato é, na maioria dos casos, mesmo utilizando Lumen, o Eloquent será utilizado, simplesmente porque sem o Eloquent o framework, de um canhão, se transforma em uma pistola. Ele simplesmente perte a maior parte do seu poder. Também é importante dizer que o Eloquent é uma das raras partes do Laravel que foram totalmente reescritas porque o sistema de ORM do Symfony (baseado no Doctrine) era lento demais (sim! O Laravel é baseado no Symfony, e usa muitos dos seus componentes por baixo dos panos).
Diferença 6 — Facades
Os facades (fachadas em tradução livre) são similares ao caso do Eloquent. Ambos os frameworks dão suporte a facades, mas somente o Lumen permite desabilitá-los completamente, a eles são desabilitados por padrão.
Mas geralmente há uma confusão de conceitos aqui. Facades são um design pattern (não vou detalhar o conceito de facades ou design patterns aqui). O que você desabilita no Lumen, na verdades são as classes que geram automaticamente uma interface estática para classes comuns, e os aliases globais que o Laravel convenientemente provê para o desenvolvedor acessar alguns módulos (como Log, Auth, etc). Mas você ainda pode utilizar a função helper app(), passando a palavra chave do facade como parâmetro (que é exatamente a mesma coisa).
Na verdade você pode, se quiser, usar o Laravel sem facades. Você pode simplesmente remover todos os aliases e sempre usar a função app(). Você não está desabilitando os facades, apenas não os está usando, que acaba sendo a mesma coisa.
Do ponto de vista de performance, é muito difícil dizer se o uso ou não de facades realmente prejudica a performance, porque é necessário um uso pesado dessa estrutura para sentir qualquer diferença, o que não acontece numa aplicação para benchmarks (se alguém quiser escrever um projeto inteiro nos dois frameworks, podemos comparar, mas é pouco provável que isso aconteça).
Diferença 7 — Geradores de código do Artisan
Artisan é a ferramenta de linha de comando do Laravel (e do Lumen). Ambos usam a mesma ferramenta. Mas o Laravel tem muito mais opções de sub-comandos disponíveis.
Um bom exemplo são os geradores de código. No Laravel temos os comandos “make” para gerar praticamente todas as estruturas de código possíveis. No Lumen é preciso fazer muitas dessas coisas copiando e colando de classes de exemplo. Não é exatamente elegante ou prático.
Mas, para mim, a grande questão é: o artisan não afeta a execução das requisições, e dito isso, eu simplesmente não entendo porque o Lumen “limou” tanto o artisan.
Isso causa zero efeitos na performance das requisições a API, mas é preciso registrar que essa é uma desvantagem do Lumen.
Extra — Comunidade, suporte, bibliotecas de terceiros
O Laravel e o Lumen compartilham a mesma comunidade (os frameworks são 90% idênticos), mas é muito fácil ver que o Laravel é mais popular. Por conta disso, é muito fácil de encontrar ajuda online (mais fácil que o Lumen). Além disso, o número de componentes criados para Laravel é consideravelmente maior do que os criados para Lumen. Geralmente, os componentes mais importantes (como Passport, Socialite, Debugbar, etc) são empacotados tanto para Laravel quanto para Lumen, mas a versão para Lumen é sempre uma versão adaptada do componente Laravel, para a qual os desenvolvedores tem muito menos cuidado na manutenção.
Resultados dos benchmarks
Eu configurei 4 pequenos projetos. Dois deles são instalações cruas do Lumen e do Laravel (padrão de fábrica). A única mudança é que no Laravel eu incluí uma rota que apenas retorna a versão do framework, no arquivo de rotas de API (exatamente como o Lumen faz). Nesses projetos, eu mantive a configuração do Lumen inalterada (sem Eloquent, sem acesso a banco, sem Facades).
Os outros dois projetos tem a mesma funcionalidade: uma pequena API, que suporta as operações de CRUD para uma única entidade (customer). Essa entidade tem 3 campos obrigatórios: first_name, last_name e email (email precisa ser um email válido). Os projetos foram construídos utilizando Laravel e Lumen. Nesse projeto o Eloquent está habilitado no Lumen (precisamos acessar o banco de dados). No Laravel, as views, rotas, middlewares e service providers que não são necessários para uma API foram removidos.
Em todos os projetos, todas as melhorias de performance possíveis/disponíveis foram realizadas (cache de rotas e config no Laravel).
O código fonte está disponível aqui.
Agora chega de conversa! Vamos aos resultados:
É fácil ver que há uma diferença gigante de performance entre as aplicações cruas (padrão de fábrica). O Lumen dá uma bela surra no Laravel (mais de 3x mais rápido). Essa é a comparação que você vai ver em todos os cantos da internet. As pessoas veem isso e repetem o mantra: “O Lumen é 4 vezes mais rápido que o Laravel, então se você vai criar uma API, use o Lumen”.
Mas com uma visão mais profunda, em uma aplicação mais próxima do mundo real (que vai fatalmente acessar um banco de dados e fazer mais do que apenas retornar uma string), percebemos que a diferença não é tão grande (em alguns casos praticamente não há diferença). Percebe-se também que em requisições que utilizam form requests, a diferença é maior (provavelmente esse é o motivo que levaram os criadores do Lumen a não incluir form requests), mas ainda, a diferença não é tão grande. E pensando que em uma aplicação real, o tempo gasto recuperando dados do banco pode (e provavelmente vai) ser muito maior, o peso dessa diferença pode se tornar ainda menor.
Conclusão
Quero deixar claro que essa parte do texto é apenas minha opinião (baseada nos resultados) e não uma resposta definitiva para a pergunta do título do artigo.
Para mim, o Laravel e o Lumen são fantásticos. Ambos são os melhores no que eles fazem. O Lumen é um micro-framework, feito para suportar micro-services. O Laravel foi feito para suportar sistemas inteiros (não apenas web sites, mas também APIs web). Ambos são apenas frameworks (ferramentas), então é muito mais sobre o que o desenvolvedor faz com eles, do que sobre o que eles podem fazer. Eu não considero uma API REST, com dezenas de endpoints, que funciona como aplicação backend de um sistema inteiro seja um micro-service. APIs REST e micro-services não são sinonimos.
Então, se o que você está construindo é uma API realmente pequena (com poucos endpoints) para servir um propósito bem específico, provavelmente você faria uma boa escolha com o Lumen. Se você chama o que você está construindo de sistema, eu iria de Laravel.
- https://medium.com/@jeffalmeida_27473/laravel-vs-lumen-what-should-i-use-63c196822b2d
Donate to Site
Renato
Developer