Глава 5.5: Роутинг для веб-страниц
Время изучения: 40 минут
1. routes/web.php
vs routes/api.php
: Два разных пульта управления
Важно еще раз закрепить фундаментальное различие:
Характеристика | routes/web.php (Веб-пульт) |
routes/api.php (API-пульт) |
---|---|---|
Основная задача | Отображение HTML-страниц, обработка форм | Предоставление данных в формате JSON для других приложений |
Состояние (State) | Stateful (с состоянием) — использует сессии и cookies | Stateless (без состояния) — каждый запрос независим |
Middleware по умолчанию | web (включает сессии, CSRF-защиту, шифрование cookies) |
api (включает "throttling" — ограничение частоты запросов) |
Префикс URL | Нет (корень вашего сайта) | /api/ (настраивается в RouteServiceProvider ) |
Аутентификация | Обычно через сессии (Login/Password) | Обычно через токены (Sanctum, Passport) |
Мы работаем с routes/web.php
, чтобы построить интерфейс для живого человека.
2. Ресурсные маршруты для веба
Подобно Route::apiResource
, для веба существует Route::resource
. Он создает маршруты для полного CRUD-цикла, включая страницы для отображения форм создания и редактирования.
Давайте создадим полный набор маршрутов для управления нашими планетами через веб-интерфейс.
Шаг 1: Создаем маршрут в routes/web.php
Закомментируйте или удалите старые маршруты для /planets
и замените их одной строкой:
use App\Http\Controllers\Web\PlanetPageController;
// Route::get('/planets', [PlanetPageController::class, 'index']);
// Route::get('/planets/{planet}', [PlanetPageController::class, 'show']);
Route::resource('planets', PlanetPageController::class);
Шаг 2: Смотрим, что было создано
Выполните в терминале команду php artisan route:list --except-vendor
:
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| GET|HEAD | planets | planets.index | ...\PlanetPageController@index | web |
| POST | planets | planets.store | ...\PlanetPageController@store | web |
| GET|HEAD | planets/create | planets.create | ...\PlanetPageController@create | web |
| GET|HEAD | planets/{planet} | planets.show | ...\PlanetPageController@show | web |
| PUT|PATCH | planets/{planet} | planets.update | ...\PlanetPageController@update | web |
| DELETE | planets/{planet} | planets.destroy | ...\PlanetPageController@destroy | web |
| GET|HEAD | planets/{planet}/edit | planets.edit | ...\PlanetPageController@edit | web |
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
Route::resource
создал для нас 7 маршрутов, включая:
planets.create
(GET/planets/create
): страница с формой создания.planets.store
(POST/planets
): обработка этой формы.planets.edit
(GET/planets/{planet}/edit
): страница с формой редактирования.planets.update
(PUT/PATCH/planets/{planet}
): обработка формы редактирования.planets.destroy
(DELETE/planets/{planet}
): удаление ресурса.
3. Именованные маршруты: Удобные "космические координаты"
Обратите внимание на колонку Name
. Laravel автоматически присвоил каждому маршруту уникальное имя (например, planets.index
). Использовать имена вместо жестко прописанных URL — это лучшая практика.
Почему? Если вы решите изменить URL с /planets
на /worlds
, вам не придется искать и менять все ссылки в ваших шаблонах. Вы просто меняете его в одном месте — в файле роутов, а имена остаются прежними.
Пример использования в Blade:
Раньше мы писали так:
Теперь мы будем писать так, используя хелпер route()
:
route('planets.show', ...)
— генерирует URL для маршрута с именемplanets.show
.['planet' => $planet->id]
— передает необходимые параметры в URL. Laravel сам подставит ID в{planet}
. Можно даже передать всю модель:['planet' => $planet]
.
4. Реализация недостающих методов в контроллере
Route::resource
создал маршруты, но соответствующие методы в PlanetPageController
нам нужно создать самим.
Откройте app/Http/Controllers/Web/PlanetPageController.php
и добавим их.
<?php
use Illuminate\Http\Request; // <-- Добавить
class PlanetPageController extends Controller
{
// index() и show() у нас уже есть
/**
* Показывает форму для создания новой планеты.
*/
public function create()
{
return view('planets.create'); // Просто возвращаем вид с формой
}
/**
* Сохраняет новую планету в базе данных.
*/
public function store(Request $request)
{
// Валидация данных из формы
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets',
'solar_system' => 'required|string|max:100',
// ... другие правила
]);
Planet::create($validated);
// Перенаправляем пользователя на страницу со списком с сообщением об успехе
return redirect()->route('planets.index')->with('success', 'Планета успешно создана!');
}
/**
* Показывает форму для редактирования планеты.
*/
public function edit(Planet $planet)
{
return view('planets.edit', ['planet' => $planet]);
}
/**
* Обновляет данные планеты в базе данных.
*/
public function update(Request $request, Planet $planet)
{
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets,name,' . $planet->id,
'solar_system' => 'required|string|max:100',
]);
$planet->update($validated);
return redirect()->route('planets.show', $planet)->with('success', 'Данные о планете обновлены!');
}
/**
* Удаляет планету.
*/
public function destroy(Planet $planet)
{
$planet->delete();
return redirect()->route('planets.index')->with('success', 'Планета списана.');
}
}
redirect()->route(...)
— перенаправляет пользователя на другой именованный маршрут.->with('success', '...')
— добавляет "флеш-сообщение" в сессию, которое будет доступно на следующей странице ровно один раз. Мы можем отобразить его в нашем Blade-шаблоне.
5. Группировка маршрутов
Если у вас много маршрутов с общими характеристиками (например, все они для админ-панели и должны иметь префикс /admin
и специальный middleware), их можно сгруппировать.
<?php
Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
// Все маршруты внутри этой группы будут иметь:
// 1. Middleware 'auth' и 'admin'
// 2. Префикс URL '/admin' (например, /admin/planets)
// 3. Префикс имени 'admin.' (например, admin.planets.index)
Route::resource('planets', PlanetPageController::class);
// Route::get('/dashboard', ...)->name('dashboard'); // -> admin.dashboard
});
Квиз для закрепления
🚀 Итог главы:
Вы освоили структурированный и профессиональный подход к организации веб-маршрутов в Laravel. Теперь вы умеете:
- Различать
web
иapi
маршруты и их предназначение. - Использовать
Route::resource
для быстрой генерации стандартных CRUD-маршрутов. - Применять именованные маршруты для создания гибкого и поддерживаемого кода.
- Создавать полные CRUD-операции в контроллере с валидацией и редиректами.
- Группировать маршруты для применения общих правил.
Навигационная система вашего "корабля" теперь отказоустойчива и готова к расширению. В финальной главе этого раздела мы соединим все полученные знания и отобразим данные о планетах, полученные через Fetch, на нашей Blade-странице.