Мне было поручено написать книгу о создании приложений для полного стека Vue.js. Поскольку многие разработчики Laravel заинтересованы в Vue (Vue теперь поставляется с Laravel), издатель хочет, чтобы книга сосредоточилась на полном стеке Vue.js с Laravel .
Готовясь к книге, я знал, что мне придется ответить на очень важный для меня вопрос: зачем кому-то даже захотеть использовать Laravel в качестве бэкенда для одностраничного приложения, когда они могут использовать Node.js?
Преимущества Node.js
Как и многие веб-разработчики, которые научились программировать за последнее десятилетие, я начал с PHP. Но так как я заинтересовался разработкой внешнего интерфейса и SPA (одностраничными приложениями), я в конечном итоге переключился на полноценный JavaScript и с тех пор не оглядывался назад.
Node.js имеет несколько очень явных преимуществ в качестве бэкэнда SPA:
- Один язык в проекте (JavaScript) означает, что его просто проще кодировать.
- Есть возможность обмениваться кодом между приложениями внешнего и внутреннего интерфейса или даже сделать приложение изоморфным.
- Node.js позволяет рендеринг на стороне сервера. Это означает, что вы можете отобразить свою страницу на сервере до того, как она попадет в браузер, что позволит пользователям быстрее увидеть страницу (есть попытки добиться этого с помощью расширений PHP / JS, но в настоящее время они не работают со многими инфраструктурами SPA как Vue, и если они делают, они намного медленнее).
- Узел имеет неблокирующий ввод-вывод и лучше обрабатывает параллельные запросы (PHP может делать это и сейчас, но, опять же, медленнее).
Застрял с PHP
Учитывая все вышесказанное, я предполагаю, почему вы должны использовать PHP для бэкэнда SPA, потому что вы должны застрять с ним , и Laravel выбран потому, что это просто лучшее из плохой ситуации.
Вы можете застрять в PHP, если:
- Основной компетенцией вас и вашей команды является PHP, и вы не чувствуете себя комфортно, переходя на полный JS.
- У вас есть устаревшая кодовая база или инфраструктура, основанная на PHP, и вы не можете ее легко изменить.
- Ваш клиент настаивает на PHP по любой причине, по которой он не будет сдвигаться с места (например, «деньги» …)
Все это на самом деле довольно веские причины для использования PHP, хотя и не очень вдохновляющие. И это то, что не имеет смысла …
Почему так много разработчиков страстно выбирают Laravel, когда их стек всегда будет хуже, чем у Node.js? Они просто невежественны или слишком упрямы, чтобы признать славу полноценного стека JavaScript?
Возвращаясь к PHP и работая с Laravel впервые за несколько лет, я теперь вижу, что в этой истории было нечто большее, чем я предполагал.
Почему Laravel отлично подходит для бэкэнда SPA
Большинство разработчиков будут упоминать о производительности и возможностях при обсуждении преимуществ инфраструктуры, но когда производительность и функциональные возможности будут соблюдены в достаточной степени, наиболее важными будут простота разработки и обслуживания.
У Laravel есть мантра «делать разработчиков счастливыми», и главная причина, по которой пользователи так увлечены Laravel, заключается в том, что он действительно выполняет это обещание. Отправившись в Laravel после нескольких лет работы с Node.js / Express, я был очень впечатлен тем, насколько он прост и элегантен.
Пример: синтаксис
Синтаксис Laravel является выразительным и простым для понимания людьми. Даже если вы никогда не видели код Laravel прежде, вы, вероятно, можете сказать, что делает следующее:
<?php
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});
- Аргумент типа функции
$user
намекает наApp\User
класс. Служебный контейнер Laravel (объясненный ниже) решит эту проблему и внедрит экземпляр этого класса в замыкание. - Laravel знает, что это модель данных, поскольку
User
класс расширяетEloquent
класс (Eloquent — это ORM Laravel). Экземпляр пользователя вы получите , будет один , где идентификатор совпадает соответствующий идентификатор из запроса URI, то есть{user}
. - Если соответствующий экземпляр модели не найден в базе данных, автоматически генерируется HTTP-ответ 404.
Это чертовски элегантно.
Объектно-ориентированные рамки являются мощными
В JavaScript теперь есть «классы», но он не является объектно-ориентированным (ОО) языком. PHP, однако, и Laravel интенсивно использует шаблоны проектирования ОО для мощного эффекта.
Давайте рассмотрим один пример, который, я думаю, вас впечатлит: служебный контейнер Laravel . Это реализация концепции объектно-ориентированного проектирования, известной как «инверсия управления», которая делает внедрение зависимостей быстрым.
Допустим, вы создаете приложение, которое позволяет пользователям обрезать свои изображения. Изображения хранятся в корзине Amazon S3, и у вас будет много транзакций с этим корзиной в вашем приложении. Вы создаете вспомогательный класс с именем, Bucket
который, при создании экземпляра, может использоваться следующим образом:
$bucket->addFile($someFile);
Созданный вами класс будет выглядеть так:
<?php
namespace App\Helpers;
class Bucket
{
protected $key;
public function __construct($key) {
$this->key = $key;
}
protected function authorize() {...}
public function addFile($file) {...}
public function deleteFile($file) {...}
}
Обратите внимание, что конструктор требует передачи ключа API, поскольку вы, очевидно, не хотите его жестко кодировать, поэтому вы будете создавать экземпляр своего класса в верхней части каждого файла следующим образом:
<?php
$key = config('amazon.api_key');
$bucket = new App\Helpers\Bucket($key);
$bucket->addFile($someFile);
Проблема заключается в том, что этот код необходимо повторять в каждом файле , не только добавляя повторения, но и создавая ошибки.
Служебный контейнер позволяет выполнить эту настройку один раз, а затем внедрить ее в любое место. Вот настройки:
<?php
$this->app->bind('App\Helpers\Bucket', function ($app) {
$key = config('amazon.api_key');
return new App\Helpers\Bucket($key);
});
Теперь app
помощник может внедрить свежий, предварительно настроенный Bucket
объект в любом месте:
<?php
$bucket = app('App\Helpers\Bucket');
$bucket->addFile($someFile);
Самое классное, что вам не нужно использовать app
помощника в функциях, так как вы можете напечатать подсказку в профиле, и Laravel автоматически разрешит его из сервисного контейнера:
<?php
public function someFunction(\App\Helpers\Bucket $bucket)
{
// $bucket is a pre-configured `Bucket` object
$bucket->addFile($someFile);
}
Заключение
Если вы хотите создать приложение в режиме реального времени с кучей одновременно работающих пользователей или если рендеринг на стороне сервера является критически важным, то, конечно, Node.js является очевидным выбором. Но для более широкого вопроса о том, может ли Laravel бороться против Node в качестве бэкэнда SPA, я бы определенно сказал да, как Laravel:
- Это простая и элегантная структура, которая делает разработку и сопровождение проще простого.
- Использует мощные объектно-ориентированные функции проектирования, которые помогут вам создать хорошо структурированный бэкэнд.
Если вы посмотрите на последние несколько выпусков Laravel (например, 5.3 с добавлением Vue в качестве платформы JS по умолчанию и 5.4 с добавлением Laravel Mix в качестве API Webpack), становится ясно, что создатели намерены сохранить актуальность Laravel в мире SPA.
Если вам интересно узнать, когда будет закончена моя книга Vue.js Full Stack Development, подпишитесь на мою рассылку, так как скоро у меня будет больше информации об этом!
Эпилог: альтернативы рендеринга сервера
В Laravel (и, честно говоря, во всех других не-JS-фреймворках) есть недостаток, что SPA-серверы рендеринга на стороне сервера часто не подходят. Например, Vue.js поддерживает только SSR с Node.js .
Однако одной из альтернатив SSR, которая часто подходит, является предварительный рендеринг . При таком подходе вы запускаете свое приложение перед его развертыванием, захватываете вывод страницы и заменяете свои HTML-файлы этим захваченным выводом. Это в значительной степени та же концепция, что и SSR, за исключением того, что она выполняется перед развертыванием в вашей среде разработки, а не на реальном сервере . Он имеет определенные оговорки, но может быть достаточным решением для вашего SPA.
Я написал больше о предварительном рендеринге с Laravel в предыдущей статье .
Другой вариант — запустить сервер Node параллельно вашему серверу Laravel и позволить Node обрабатывать SSR.