Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Ресурсная маршрутизация PHP: Laravel

Фактически, любой CRUD состоит из 7 маршрутов, контроллера и шаблонов. Причём большая часть этого кода идентична, особенно маршруты. Они не содержат логики и всегда строятся по одному и тому же принципу.

Laravel частично заимствовал из Rails ещё один механизм, который называется "ресурсная маршрутизация". Он упрощает создание типичных CRUD, за счёт полной унификации всех маршрутов и способов их обработки. Вместо описания 7 разных маршрутов, ресурсная маршрутизация позволяет указать один метамаршрут:

<?php

Route::resource('articles', ArticleController::class);

Внутри себя он превращается в те самые семь маршрутов, которые мы реализовывали в предыдущих уроках. Их можно увидеть с помощью команды artisan:

$ php artisan route:list
+-----------+-------------------------+------------------+---------+
| Method    | URI                     | Name             | Action  |
+-----------+-------------------------+------------------+---------+
| GET|HEAD  | /                       |                  | Closure |
| GET|HEAD  | articles                | articles.index   | index   |
| POST      | articles                | articles.store   | store   |
| GET|HEAD  | articles/create         | articles.create  | create  |
| GET|HEAD  | articles/{article}      | articles.show    | show    |
| PUT|PATCH | articles/{article}      | articles.update  | update  |
| DELETE    | articles/{article}      | articles.destroy | destroy |
| GET|HEAD  | articles/{article}/edit | articles.edit    | edit    |
+-----------+-------------------------+------------------+---------+
# Обратите внимание на имя плейсхолдера. Ниже станет понятно почему здесь article, а не id

Довольно неплохо. В проектах где подобных CRUD много (любой типичный веб-проект), ресурсный маршрутизатор очень помогает. Он не просто сокращает количество кода, но и даёт хорошую унификацию. Нужно меньше думать и меньше спорить. Всё уже спроектировано.

Следующий шаг – упрощение контроллера. Во-первых можно сразу сгенерировать контроллер, со всеми нужными обработчиками. Во-вторых, этот контроллер можно интегрировать с нужной моделью:

php artisan make:controller ArticleController --resource --model Article

На выходе получим такой контроллер:

<?php

namespace App\Http\Controllers;

use App\Models\Article;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Article  $article
     * @return \Illuminate\Http\Response
     */
    public function show(Article $article)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Article  $article
     * @return \Illuminate\Http\Response
     */
    public function edit(Article $article)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Article  $article
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Article $article)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Article  $article
     * @return \Illuminate\Http\Response
     */
    public function destroy(Article $article)
    {
        //
    }

Обратите внимание на параметры обработчиков. Laravel самостоятельно находит нужную сущность и достаёт её из базы данных. Это позволяет хоть немного, но сократить код.

Ресурсы могут быть вложенными. Это даёт возможность строить пути, отражающие зависимости между сущностями на сайте:

# Примеры с Хекслета

# Урок /courses/{course}/lessons/{lesson}
/courses/js-testing/lessons/asserts
# Список пройденных курсов /u/{user}/courses
/u/mokevnin/courses

Принцип построения адресов точно такой же, как и для обычного ресурса, но с включением указания на родительский ресурс:

# Список
/entities/{entity}/subentities

# Сущность
/entities/{entity}/subentities/{subentity}

# Все остальные маршруты строятся по такому же принципу.
# Впереди добавляется /entities/{entity}.

Вложенный ресурс можно генерировать автоматически:

php artisan make:controller ArticleCommentController --resource --model ArticleComment --parent Article

Например, вот так выглядит ресурс комментарии к статьям:

<?php

Route::resource('articles.comments', ArticleCommentController::class);

Для вложенного ресурса, в экшены, кроме самой сущности передаётся и родительская сущность:

<?php

# /articles/{article}/comments/{comment}
# Обе сущности можно получить через параметры
public function edit(Article $article, ArticleComment $comment)
{
    return view('article_comment.edit', compact('article', 'comment'));
}

Немного по другому начинает работать хелпер route. Для построения ссылок, там где участвуют оба ресурса, нужно использовать массив для их передачи:

<?php

route('articles.comments.edit', [$article, $comment]);

Заключение

Ресурсная маршрутизация – удобный механизм, позволяющий немного упростить создание CRUD. Он берёт на себя много работы и даёт программисту возможность сосредоточиться на логике.

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


Самостоятельная работа

  1. Удалите все маршруты связанные со статьями
  2. Удалите контроллер статей (шаблоны оставьте)
  3. Добавьте ресурсную маршрутизацию articles
  4. Сгенерируйте для него контроллер ArticleController
  5. Реализуйте CRUD

Дополнительные материалы

  1. Ресурсная маршрутизация

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнения
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 120 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы PHP-разработчик
Профессия
Разработка веб-приложений на Laravel
22 сентября 8 месяцев

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»