Laravel vs Lumen — Что использовать?

Laravel vs Lumen

Какова же реальная разница между этими двумя братскими фреймворками, и стоит ли отказываться от некоторых функций старшего брата (Laravel), в обмен на быстродействие младшего брата (Lumen). Я думаю, что главный вопрос это «насколько быстрее?» Цель статьи не в том, чтобы дать окончательное решение, а в том, чтобы читатель мог оценить собранную мной информацию и сам принять решение. Конечно, здесь нет абсолютных истин, всё сильно зависит от потребностей проекта.

Для начала давайте уточним, что мы сравниваем. Если вы делаете MVC сайт/приложение, для которых необходимо шаблоны и хранение информации о сессиях — обсуждать нечего: только Laravel. Просто потому, что Lumen не поддерживает эти вещи. Lumen был создан для поддержки stateless API (API без сохранения состояния) (это может и Laravel). Поэтому мы сравним только то, что могут делать обе платформы — обслуживание API без сохранения состояния.

Прежде чем начать сравнение, давайте быстро определим основные различия между фреймворками, кратко прокомментируем каждое из них (плюсы и минусы) и, в конце, сравним их в тестах (только эталонные тесты, имеющие смысл. Вы поймете, о чём я говорю).

Различие 1 — Шаблонизатор

Это самое известное и обсуждаемое различие. Laravel использует Blade для создания шаблонов (а это потрясающий инструмент), а у Lumen вообще нет никакого движка для этого.

Я не рассматриваю эту разницу в сравнении, потому что если мы используем Laravel для обслуживания API без сохранения состояния, шаблонов вообще не будет. Движок то будет, но мы просто не будем его использовать (но это не является большой проблемой).

Различие 2 — Сессии

У Lumen нет никакого механизма для обработки сессий, поскольку он предназначен для работы без сохранения состояния. У Laravel есть мощный менеджер сессий.

Опять же, это не большая проблема, так как мы создаем stateless API, и движок сессий от Laravel будет полностью деактивирован (так же, как шаблонизатор).

Различие 3 — Маршрутизация

А тут существенное различие! Механизм маршрутизации Laravel РЕАЛЬНО мощный. Он позволяет вам создавать ресурсные маршруты (создавая все маршруты для операций CRUD одновременно) и автоматически связывать модели Eloquent с переменными, передаваемых в маршруте (и он позаботится вернуть ошибку, если ресурс не найден). Это дает разработчику возможность держать код в контроллере чистым и элегантным. Само определение маршрутов элегантно. Маршрутизатор Laravel также поддерживает кеширование маршрутов, что значительно повышает скорость маршрутизации. Конечно, у всех этих чудес есть цена. Механизм маршрутизации Laravel (даже с включенным кэшем) не очень быстрый, и поэтому Lumen был собран с простым, но более быстрым сторонним маршрутизатором. Маршрутизатор Lumen не поддерживает автоматическую привязку моделей (model binding) (что является самым большим недостатком, на мой взгляд), а также не поддерживает кэширование (но это не проблема, поскольку всё еще быстрее). Я не буду обсуждать элегантность определения маршрута, так как это просто синтаксический сахар.

Вопрос здесь в том, что мы отказываемся от хорошей функции (автоматическая привязка модели) в обмен на скорость. Таким образом, нужно думать, стоит ли увеличение скорости потери этой функции. Оставим это обсуждение до тестов.

Разница 4 — Form Request

Запросы форм — это структуры, используемые Laravel для представления тела запроса и логики его валидации. Первоначально он был разработан для отображения форм HTML (поэтому он называется запросом формы), но его можно использовать для любого запроса (включая запросы REST). Эти структуры заботятся о валидации, возвращая ответы об ошибках в проверках при сбое (код ошибки, полезная нагрузка ответа, сообщения об ошибках). Всё это до попадания в контроллер. Все, что вам нужно сделать, это ввести ожидание типа (type-hint) переменной запроса в класс запроса формы. Кроме того, в Laravel нет встроенного механизма очищения (sanitizing engine), но вы можете легко добавить его при помощи сторонних библиотек, обеспечивающих функцию очистки запросов в дополнение к проверке. Тогда, вы сможете быть уверены, что все данные, попавшие в ваш контроллер, валидны, что сделает код вашего контроллера ЧРЕЗВЫЧАЙНО чистым (вы увидите это при сравнении кода).

Lumen не поддерживает запросы формы, это связано с разными маршрутизаторами, о чем я рассказывал выше (он не может автоматически привязывать тело запроса к запросу формы). Все проверки и очистки данных должны происходить внутри контроллера.

Разница 5 — Eloquent

Оба фреймворка поддерживают Eloquent (Ларавельный движок ORM), но только в Lumen его можно полностью отключить (по умолчанию он и отключен).

Это сложное обсуждение. Когда мы говорим о MVC фреймворках, ORM — чрезвычайно взаимосвязанный вопрос. Обычно, когда вы используете MVC фреймворк — вам нужен ORM, потому что это один из самых больших источников гибкости, который вы выигрываете с MVC. Конечно, отправка select непосредственно в базу данных более производительна, чем использование механизма ORM. Но вы действительно хотите вручную обрабатывать все отношения, касты и все, что с этим связано? Вы хотите рискнуть взять это на себя? Как насчет обслуживания всего этого?

Дело в том, что в большинстве случаев даже с Lumen вы захотите использовать Eloquent, потому что без Eloquent фреймворк превращается из базуки в пистолет. Он просто теряет большую часть своей мощи. Также важно сказать, что Eloquent — это одна из частей Laravel, которая была полностью переписана с нуля, потому что механизм ORM от Symfony (основанный на Doctrine) был чрезвычайно медленным (да! Laravel основан на Symfony и использует множество её компонентов под капотом).

Разница 6 — Фасады

Фасады похожи на Eloquent в этом плане. Оба фреймворка поддерживают их, но только Lumen дает возможность полного отключения Фасадов, и, по умолчанию, они отключены.

Но здесь мы имеем концепцию, в большинстве случаев неправильно понимаемую. Фасады — это паттерн проектирования (я не буду вдаваться в концепцию фасадов). На самом деле в Lumen вы отключаете классы фасадов и глобальные псевдонимы, которые Laravel предоставляет разработчику для простого доступа к некоторым модулям (таким как Log, Auth и т.д.). Но вы все еще можете использовать функцию app(), передавая читателя фасада (facade accessor) как параметр (что, по сути, то же самое).

Фактически, если вы хотите использовать Laravel без фасадов, вы можете просто удалить все определения псевдонимов и всегда использовать функцию app(). Вы не отключаете их, а просто не используете, что в конечном счете то же самое.

С точки зрения производительности, трудно сказать, действительно ли использование фасадов наносит ей ущерб, потому что необходимо действительно интенсивно использовать эти структуры, чтобы заметить разницу, а это не делается в тестовых приложениях.

Разница 7 — Генераторы Artisan

Artisan — инструмент командной строки для Laravel и Lumen. Оба используют одну и ту же структуру. Но у Laravel гораздо больше команд, чем у Lumen.

Хороший пример — генераторы. В Laravel у вас есть команды «make» для генерации практически любой структуры кода. В Lumen вы делаете это копипастингом из файла примеров. Вообще не весело.

Но главный вопрос в том, что artisan вообще не влияет на время выполнения запросов, и я вообще не понимаю, почему artisan в Lumen был собран таким куцым.

Нет никакой разницы в производительности API, но мы должны отметить, что это отрицательный момент у Lumen.

Дополнительно — Сообщество, поддержка, сторонние библиотеки

Laravel и Lumen в основном живут в одном сообществе, но понятно, что Laravel более популярен. Из-за этого гораздо проще найти помощь онлайн (легче, чем для Lumen). Кроме того, количество компонентов, сделанных для Laravel, значительно больше, чем для Lumen. Обычно самые большие компоненты (такие как Passport, Socialite, Debugbar и т.д.) собраны как для Laravel, так и для Lumen, но версия Lumen всегда является адаптированной версией компонента Laravel.

Результаты тестов

Я создал 4 маленьких проекта. Два из них — свежие установки Lumen и Laravel. Уникальным изменением в Laravel является то, что в файл маршрутов API я включил маршрут, который просто возвращает версию приложения (как это делает Lumen). Конфигурация Lumen дефолтная (нет Eloquent, нет доступа к базе данных, нет фасадов).

Два других проекта — это небольшое API, в котором есть операции CRUD для одного объекта (клиента). У этого объекта есть 3 обязательных поля: first_name, last_name и email (адрес электронной почты должен быть валидным). Проекты были построены с использованием Laravel и Lumen. В этом проекте в Lumen включен Eloquent (нам нужен доступ к базе данных). На в Laravel мы полностью удалили шаблоны, все маршруты, мидлвары и сервис-провайдеры, которые не нужны для stateless API.

Во всех проектах были выполнены все возможные/доступные настройки (кеширование маршрутов и конфигурация в Laravel).

Исходный код можно скачать здесь.

Довольно слов, вот результаты:

Laravel vs Lumen - behcbmarks

Как видите, огромная разница в производительности между свежими проектами. Lumen просто надрал задницу Laravel. И подобные сравнения по всему интернету. Люди повторяют как мантру: «Lumen как минимум в 4 раза быстрее, чем Laravel, поэтому, если вы хотите API, используйте Lumen».

Но если взглянуть глубже, ближе к реальному приложению (которое обращается к базе данных и делает больше, чем просто возвращает строку), мы видим, что разница не так уж велика (иногда практической разницы нет вообще). Мы видим, что запросы, использующие Form Request, отличаются большей разницей (возможно, именно поэтому разработчики Lumen решили не использовать их не использовать), но, тем не менее, разница не так велика. Думаю, что реальное приложение, возможно, будет тратить гораздо больше времени на получение данных из базы данных, и эта разница может станет еще меньше.

Заключение

Этот статья — только мое мнение, а не окончательный ответ на вопрос из названия этой статьи.

На мой взгляд, и Laravel, и Lumen великолепны. Оба являются лучшими в том, для чего они были созданы. Lumen — это микро-фреймворк, созданный для поддержки микросервисов. Laravel был создан для поддержки больших систем (не только сайтов, но и веб-API). Оба являются просто фреймворками (инструментами), поэтому разработчик должен заставить их работать наилучшим образом. Я не думаю, что Rest API с десятками конечных точек, который обеспечивает работу всей системы, является микросервисом. Rest API и микросервисы это не синонимы.

Итак, если вы создаете маленький API (с несколькими конечными точками) для определенной цели, используйте Lumen. Если вы называете, то что создаете — системой, то я бы рекомендовал Laravel.

Автор: Jeff Almeida
Перевод: Алексей Широков

Наш Телеграм-канал — следите за новостями о Laravel.