Статьи

Одностраничные бэкэнды приложений: где Laravel превосходит Node.js

Мне было поручено написать книгу о создании приложений для полного стека Vue.js. Поскольку многие разработчики Laravel заинтересованы в Vue (Vue теперь поставляется с Laravel), издатель хочет, чтобы книга сосредоточилась на полном стеке Vue.js с Laravel .

Готовясь к книге, я знал, что мне придется ответить на очень важный для меня вопрос: зачем кому-то даже захотеть использовать Laravel в качестве бэкенда для одностраничного приложения, когда они могут использовать Node.js?

Преимущества Node.js

Как и многие веб-разработчики, которые научились программировать за последнее десятилетие, я начал с PHP. Но так как я заинтересовался разработкой внешнего интерфейса и SPA (одностраничными приложениями), я в конечном итоге переключился на полноценный JavaScript и с тех пор не оглядывался назад.

Node.js имеет несколько очень явных преимуществ в качестве бэкэнда SPA:

  1. Один язык в проекте (JavaScript) означает, что его просто проще кодировать.
  2. Есть возможность обмениваться кодом между приложениями внешнего и внутреннего интерфейса или даже сделать приложение изоморфным.
  3. Node.js позволяет рендеринг на стороне сервера. Это означает, что вы можете отобразить свою страницу на сервере до того, как она попадет в браузер, что позволит пользователям быстрее увидеть страницу (есть попытки добиться этого с помощью расширений PHP / JS, но в настоящее время они не работают со многими инфраструктурами SPA как Vue, и если они делают, они намного медленнее).
  4. Узел имеет неблокирующий ввод-вывод и лучше обрабатывает параллельные запросы (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;
});
  1. Аргумент типа функции $userнамекает на App\Userкласс. Служебный контейнер Laravel (объясненный ниже) решит эту проблему и внедрит экземпляр этого класса в замыкание.
  2. Laravel знает, что это модель данных, поскольку Userкласс расширяет Eloquentкласс (Eloquent — это ORM Laravel). Экземпляр пользователя вы получите , будет один , где идентификатор совпадает соответствующий идентификатор из запроса URI, то есть {user}.
  3. Если соответствующий экземпляр модели не найден в базе данных, автоматически генерируется 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.