Laravel и React — две популярные технологии веб-разработки, используемые для создания современных веб-приложений. Laravel — это серверная PHP-инфраструктура, а React — клиентская JavaScript-библиотека. Этот учебник служит введением в Laravel и React, объединяя их для создания современного веб-приложения.
В современном веб-приложении сервер имеет ограниченную работу по управлению внутренним сервером через некоторые конечные точки API (Application Programming Interface). Клиент отправляет запросы на эти конечные точки, а сервер возвращает ответ. Однако сервер не заботится о том, как клиент отображает представление, что полностью соответствует принципу разделения проблем. Эта архитектура позволяет разработчикам создавать надежные приложения для Интернета, а также для различных устройств.
В этом руководстве мы будем использовать последнюю версию Laravel версии 5.5 для создания RESTful back-end API. Внешний интерфейс будет состоять из компонентов, написанных на React. Мы создадим приложение для создания списка продуктов. Первая часть урока будет больше сфокусирована на концепциях Laravel и серверной части. Давайте начнем.
Вступление
Laravel — это PHP-фреймворк, разработанный для современного Интернета. У этого есть выразительный синтаксис, который одобряет соглашение по парадигме конфигурации . Laravel имеет все функции, которые вам нужны, чтобы начать проект прямо из коробки. Но лично мне нравится Laravel, потому что он превращает разработку с PHP в совершенно другой опыт и рабочий процесс.
С другой стороны, React — это популярная библиотека JavaScript, разработанная Facebook для создания одностраничных приложений. React помогает вам разбить ваше представление на компоненты, где каждый компонент описывает часть пользовательского интерфейса приложения. Компонентный подход имеет дополнительное преимущество повторного использования и модульности компонентов.
Почему Ларавел и Реакт?
Если вы разрабатываете для Интернета, вы можете быть склонны использовать одну кодовую базу как для сервера, так и для клиента. Однако не каждая компания дает разработчику свободу использовать технологию по своему выбору и по ряду веских причин. Использование стека JavaScript для всего проекта является текущей нормой, но ничто не мешает вам выбрать две разные технологии для серверной и клиентской сторон.
Итак, насколько хорошо Laravel и React подходят друг другу? Довольно хорошо, на самом деле. Хотя в Laravel задокументировано, что он поддерживается для Vue.js, который является еще одной платформой JavaScript, мы будем использовать React для внешнего интерфейса, поскольку он более популярен.
Предпосылки
Прежде чем начать, я собираюсь предположить, что у вас есть общее представление об архитектуре RESTful и о том, как работают конечные точки API. Кроме того, если у вас есть опыт работы в React или Laravel, вы сможете извлечь максимальную пользу из этого урока.
Однако, если вы новичок в обеих платформах, не беспокойтесь. Учебник написан с точки зрения начинающего, и вы сможете наверстать упущенное без особых проблем. Вы можете найти исходный код руководства на GitHub .
Установка и настройка вашего проекта Laravel
Laravel использует Composer для управления всеми зависимостями. Итак, прежде чем начать работу с Laravel, скачайте и установите Composer на свой компьютер. Вам также может потребоваться настроить переменную среды пути, чтобы Composer был доступен глобально.
Запустите следующую команду, чтобы загрузить установщик laravel.
1
|
composer global require «laravel/installer»
|
Если вы правильно настроили $PATH
и добавили ~/.composer/vendor/bin
в свой путь, вы сможете сгенерировать новый проект Laravel следующим образом:
1
|
laravel new PROJECT-NAME
|
Кроме того, вы можете использовать Composer для создания нового проекта без установщика laravel.
1
|
composer create-project —prefer-dist laravel/laravel blog
|
Если все идет хорошо, вы сможете разместить свое приложение на сервере разработки по адресу http://localhost:8000
.
1
|
php artisan serve
|
Примечание: Artisan — это инструмент командной строки, без которого вы не можете жить, работая с Laravel. Artisan принимает большой список команд, которые позволяют генерировать код для вашего приложения. Запустите php
artisan list
для просмотра всех доступных команд artisan.
Конфигурирование среды
Ваше приложение будет иметь файл .env внутри корневого каталога. Вся информация о конфигурации конкретной среды объявляется здесь. Создайте базу данных для своего приложения, если вы этого еще не сделали, и добавьте детали базы данных в файл .env .
1
2
3
4
5
6
|
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sampledb
DB_USERNAME=root
DB_PASSWORD=
|
Понимание моделей, маршрутов и контроллеров
Laravel — это фреймворк, который следует архитектуре Model-View-Controller (MVC). Вообще говоря, MVC помогает вам отделить запросы к базе данных (Модель) от логики, связанной с тем, как должны обрабатываться запросы (Контроллер) и как должен отображаться макет (Представление). Изображение ниже демонстрирует работу типичного приложения Laravel.
Поскольку мы создаем API с использованием Laravel, мы ограничимся обсуждением модели и контроллера. Мы рассмотрим наши варианты создания View во второй части этого урока.
Маршрутизатор
Когда сервер получает HTTP-запрос, Laravel пытается сопоставить его с маршрутом, зарегистрированным в любом из файлов маршрута. Все файлы маршрутов находятся внутри каталога маршрутов. маршруты / web.php содержат маршрут для веб-интерфейса, тогда как маршруты / api.php содержат маршрут для API. Маршруты, зарегистрированные в api.php, будут иметь префикс /api
(как в localhost: 3000 / api). Если вам нужно изменить это поведение, RouteServiceProvider
класс RouteServiceProvider в /app/Providers/RouteServiceProvider.php и внесите в него изменения.
Поскольку мы создаем приложение для создания списка продуктов, здесь представлены конечные точки для API и действия HTTP, связанные с этими конечными точками.
- ПОЛУЧИТЬ
/products/
: получить все продукты. - GET
/product/{id}
: получить продукт, соответствующийid
. - POST
/products
: создайте новый продукт и вставьте его в базу данных. - PUT
/products/{id}
: обновить существующий продукт, соответствующийid
. - DELETE
/products/{id}
: Удалить продукт с указаннымid
.
Давайте разберемся в терминологии. GET, POST, PUT и DELETE — это HTTP-глаголы (более известные как HTTP-методы), в основном необходимые для создания службы RESTful. /products
— это URI, связанный с ресурсом products. Методы HTTP запрашивают у сервера выполнение желаемого действия с данным ресурсом.
Маршрутизатор позволяет вам объявлять маршруты для ресурса вместе с методами HTTP, которые нацелены на этот ресурс. Вот пример файла маршрутов, который возвращает некоторые жестко закодированные данные.
маршруты / api.php
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/**
** Basic Routes for a RESTful service:
**
** Route::get($uri, $callback);
** Route::post($uri, $callback);
** Route::put($uri, $callback);
** Route::delete($uri, $callback);
**
**/
Route::get(‘products’, function () {
return response([‘Product 1’, ‘Product 2’, ‘Product 3’],200);
});
Route::get(‘products/{product}’, function ($productId) {
return response()->json([‘productId’ => «{$productId}»], 200);
});
Route::post(‘products’, function() {
return response()->json([
‘message’ => ‘Create success’
], 201);
});
Route::put(‘products/{product}’, function() {
return response()->json([
‘message’ => ‘Update success’
], 200);
});
Route::delete(‘products/{product}’,function() {
return response()->json(null, 204);
});
|
Если вы хотите убедиться, что маршруты работают должным образом, вы должны использовать такой инструмент, как POSTMAN или curl.
Модель продукта
Ресурсу товаров нужна модель, которая может взаимодействовать с базой данных. Модель — это слой, который находится поверх базы данных и скрывает весь специфичный для базы данных жаргон. Laravel использует Eloquent ORM для моделирования базы данных.
Eloquent ORM, включенный в Laravel, обеспечивает красивую и простую реализацию ActiveRecord для работы с вашей базой данных. Каждая таблица базы данных имеет соответствующую «Модель», которая используется для взаимодействия с этой таблицей. Модели позволяют запрашивать данные в ваших таблицах, а также вставлять новые записи в таблицу.
— Laravel Docs
Как насчет определения схемы базы данных? Миграция Ларавела позаботится об этом. Artisan имеет команду миграции, которая позволяет вам определять схему и постепенно обновлять ее на более позднем этапе. Давайте создадим модель и миграцию для сущности Product.
1
|
$ php artisan make:model Product -m
|
Примечание: существует множество команд Artisan, и их легко потерять. Таким образом, каждая команда ремесленника включает вспомогательный экран, который отображает дополнительную информацию, такую как доступные параметры и аргументы. Чтобы перейти на страницу справки, имени команды должен предшествовать help
. Запустите следующую команду справки, чтобы узнать, что означает опция -m
: $ php artisan help make:model
.
Вот сгенерированный файл миграции.
базы данных / миграция / timestamp_create_products_table.php
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProductsTable extends Migration
{
public function up()
{
Schema::create(‘products’, function (Blueprint $table) {
$table->increments(‘id’);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists(‘products’);
}
}
|
Метод up
вызывается при переносе новых таблиц и столбцов в базу данных, тогда как метод down
вызывается при откате миграции. Мы создали схему для таблицы с тремя строками: id
, created_at
и updated_at
. Метод $table->timestamps()
отвечает за поддержание столбцов created_at
и updated_at
. Давайте добавим еще пару строк к определению схемы.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
/* Let’s add columns for title, description, price, availability */
public function up()
{
Schema::create(‘products’, function (Blueprint $table) {
$table->increments(‘id’);
$table->timestamps();
$table->string(‘title’);
$table->text(‘description’);
$table->integer(‘price’);
$table->boolean(‘availability’);
});
}
|
Мы обновили схему четырьмя новыми столбцами. Конструктор схемы Laravel поддерживает различные типы столбцов, такие как string
, text
, integer
, boolean
и т. Д.
Чтобы выполнить отложенные миграции, вам нужно выполнить следующую команду:
1
|
php artisan migrate
|
По условию Laravel предполагает, что модель Product связана с таблицей продуктов . Однако если вам нужно связать модель с настраиваемым именем таблицы, вы можете использовать свойство $table
для объявления имени таблицы. Затем модель будет связана с таблицей с именем custom_products .
1
|
protected $table = ‘custom_products’;
|
Но мы будем просты и будем придерживаться соглашения. Сгенерированная модель продукта находится в каталоге app / . Хотя класс модели может показаться пустым, он оснащен различными методами построения запросов, которые можно использовать для запроса к базе данных. Например, вы можете использовать Product::all()
для получения всех продуктов или Product::find(1)
для получения конкретного продукта с идентификатором 1.
Модели Laravel имеют встроенный механизм защиты от уязвимости массового назначения . Свойство fillable
используется для объявления имен атрибутов, которые можно безопасно назначать массовым образом.
Приложение / product.php
1
2
3
|
/* Add the fillable property into the Product Model */
protected $fillable = [‘title’, ‘description’, ‘price’, ‘availability’];
|
Приведенный выше код заносит в белый список атрибуты title
, description
, price
и availability
и обрабатывает их как массовые. Теперь мы можем использовать метод Product::create
для вставки новых строк в таблицу products.
Заполнение базы данных
Laravel позволяет вам заполнить вашу базу данных разработки и производства фиктивными данными, которые вы затем можете использовать для тестирования ваших конечных точек API. Вы можете создать начальный класс, выполнив следующую команду Artisan.
1
|
$ php artisan make:seeder ProductsTableSeeder
|
Сгенерированные файлы сеялки будут помещены в каталог database / seed .
Чтобы сгенерировать фиктивные данные, вы можете использовать что-то вроде str_random(10)
которое возвращает случайную строку. Но если вам нужны данные, которые достаточно близки к фактическим данным, вы должны использовать что-то вроде библиотеки фейеров. Faker — сторонняя библиотека, которая поставляется с платформой Laravel для генерации поддельных данных.
База данных / Семена / ProductsTableSeeder.php
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
use App\Product;
class ProductsTableSeeder extends Seeder
{
public function run()
{
$faker = \Faker\Factory::create();
// Create 50 product records
for ($i = 0; $i < 50; $i++) {
Product::create([
‘title’ => $faker->title,
‘description’ => $faker->paragraph,
‘price’ => $faker->randomNumber(2),
‘availability’ => $faker->boolean(50)
]);
}
}
}
|
Выполните команду db:seed
artisan, чтобы заполнить базу данных.
1
|
$ php artisan db:seed —class=ProductsTableSeeder
|
Давайте вернемся к routs / api.php и заполните недостающие фрагменты.
маршруты / api.php
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
/**
**Basic Routes for a RESTful service:
**Route::get($uri, $callback);
**Route::post($uri, $callback);
**Route::put($uri, $callback);
**Route::delete($uri, $callback);
**
*/
Route::get(‘products’, function () {
return response(Product::all(),200);
});
Route::get(‘products/{product}’, function ($productId) {
return response(Product::find($productId), 200);
});
Route::post(‘products’, function(Request $request) {
$resp = Product::create($request->all());
return $resp;
});
Route::put(‘products/{product}’, function(Request $request, $productId) {
$product = Product::findOrFail($productId);
$product->update($request->all());
return $product;
});
Route::delete(‘products/{product}’,function($productId) {
Product::find($productId)->delete();
return 204;
});
|
Контроллер
Файл маршрута в настоящее время содержит логику для маршрутизации и обработки запросов. Мы можем переместить логику обработки запросов в класс Controller, чтобы наш код был лучше организован и более читабелен. Давайте сначала сгенерируем класс контроллера.
1
|
$ php artisan make:controller ProductsController
|
Класс Controller состоит из различных методов (index, show, store, update и delete), которые соответствуют различным действиям HTTP. Я переместил логику обработки запросов с маршрута на контроллер.
приложение / HTTP / Контроллеры / ProductsController.php
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;
class ProductsController extends Controller
{
public function index()
{
return Product::all();
}
public function show(Product $product)
{
return $product;
}
public function store(Request $request)
{
$product = Product::create($request->all());
return response()->json($product, 201);
}
public function update(Request $request, Product $product)
{
$product->update($request->all());
return response()->json($product, 200);
}
public function delete(Product $product)
{
$product->delete();
return response()->json(null, 204);
}
}
|
маршруты / api.php
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
/**
**Basic Routes for a RESTful service:
**Route::get($uri, $callback);
**Route::post($uri, $callback);
**Route::put($uri, $callback);
**Route::delete($uri, $callback);
**
*/
Route::get(‘products’, ‘ProductsController@index’);
Route::get(‘products/{product}’, ‘ProductsController@show’);
Route::post(‘products’,’ProductsController@store’);
Route::put(‘products/{product}’,’ProductsController@update’);
Route::delete(‘products/{product}’, ‘ProductsController@delete’);
|
Если вы не заметили, я внедрил экземпляр Product в методы контроллера. Это пример неявного связывания Laravel. Laravel пытается сопоставить имя экземпляра модели Product $product
с именем сегмента URI {product}
. Если совпадение найдено, экземпляр модели Product внедряется в действия контроллера. Если база данных не имеет продукта, она возвращает ошибку 404. Конечный результат такой же, как и раньше, но с меньшим количеством кода.
Откройте POSTMAN, и конечные точки для продукта должны работать. Убедитесь, что у вас включен заголовок Accept : application/json
.
Проверка и обработка исключений
Если вы перейдете на несуществующий ресурс, это то, что вы увидите.
NotFoundHTTPException
— это то, как Laravel отображает ошибку 404. Если вы хотите, чтобы сервер возвращал ответ JSON, вам придется изменить поведение обработки исключений по умолчанию. В Laravel есть класс Handler, предназначенный для обработки исключений, который находится в app / Exceptions / Handler.php . Класс в основном имеет два метода: report()
и render()
. Метод report
полезен для создания отчетов и регистрации событий исключений, тогда как метод render используется для возврата ответа при обнаружении исключения. Обновите метод рендеринга, чтобы он возвращал ответ JSON:
Приложение / Исключение / handler.php
01
02
03
04
05
06
07
08
09
10
11
12
|
public function render($request, Exception $exception)
{
if ($exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException)
{
return response()->json([
‘message’ => ‘Resource not found’
], 404);
}
return parent::render($request, $exception);
}
|
Laravel также позволяет нам проверять входящие HTTP-запросы с использованием набора правил проверки и автоматически возвращать ответ JSON, если проверка не удалась. Логика для проверки будет размещена внутри контроллера. Объект Illuminate\Http\Request
предоставляет метод validate, который мы можем использовать для определения правил проверки. Давайте добавим несколько проверок правильности в метод store.
приложение / HTTP / Контроллеры / ProductsController.php
01
02
03
04
05
06
07
08
09
10
11
12
|
public function store(Request $request)
{
$this->validate($request, [
‘title’ => ‘required|unique:products|max:255’,
‘description’ => ‘required’,
‘price’ => ‘integer’,
‘availability’ => ‘boolean’,
]);
$product = Product::create($request->all());
return response()->json($product, 201);
}
|
Резюме
Теперь у нас есть работающий API для приложения с перечнем продуктов. Однако в API отсутствуют основные функции, такие как аутентификация и ограничение доступа неавторизованным пользователям. Laravel имеет встроенную поддержку аутентификации, и создать API для нее относительно просто. Я рекомендую вам реализовать API аутентификации в качестве упражнения.
Для тех из вас, кто только начинает работать с Laravel или хочет расширить свои знания, сайт или приложение с помощью расширений, у нас есть множество вещей, которые вы можете изучить на Envato Market .
Теперь, когда мы закончили работу с серверной частью, мы переключим наше внимание на интерфейсные концепции. Оставайтесь с нами для второй части серии. Поделитесь своими мыслями в комментариях.