Skip to content

Controllers, Routing, Middleware, Validation

Роль контроллера

Контроллер — тонкая прослойка. Три действия:

  1. Принять и провалидировать input (FormRequest)
  2. Вызвать сервис
  3. Вернуть response (view / json / redirect)

Если в методе контроллера больше 10 строк логики — она должна быть в Service.

Routing

Route Model Binding

  • По slug — для публичных сущностей ({category:slug}, {product:slug})
  • По id — только для внутренних/admin сущностей
  • Вложенные модели с scopeBindings() — Laravel автоматически проверяет принадлежность child к parent

Группировка

  • По prefix — общий URL-префикс (/catalog/*, /api/*)
  • По middleware — общие middleware (throttle, auth)
  • По name — общий prefix для имён роутов (catalog.index, catalog.show)

Именование

Каждый роут ДОЛЖЕН иметь имя через ->name(). Ссылки в коде — только через route('name'), никогда хардкод URL.

Редиректы

  • 301 — permanent (для SEO, при переименовании URL)
  • 302 — temporary (для временных перенаправлений)
  • При любом изменении URL — обязателен 301 со старого адреса

Fallback

Определять fallback-роут для 404 — чтобы кастомная страница, а не дефолтная Laravel.


FormRequest (Validation)

  • Отдельный FormRequest-класс для каждой формы/endpoint
  • Валидация НИКОГДА не в контроллере — только в FormRequest
  • authorize() — true для публичных форм, проверка прав для защищённых
  • messages() — кастомные сообщения на русском для пользовательских форм

Правила валидации

  • required vs nullable — осознанный выбор, не "на всякий случай"
  • max:255 на все string поля — защита от переполнения
  • email:rfc,dns — проверяет формат И существование домена
  • exists:table,column — для FK, проверка что связанная запись существует
  • unique:table,column с ignoreRecord при update
  • Regex для телефонов и специфичных форматов
  • Кастомные правила через Rule:: или invokable rule class

Middleware

Регистрация

Laravel 11+: в bootstrap/app.php через ->withMiddleware(), не в Kernel.php.

Типичные middleware

MiddlewareНазначениеГде применять
throttle:X,YRate limitingAPI POST endpoints
Кастомный PageCacheКеш GET-страниц в RedisПубличные GET-роуты
Кастомный ResolveCityОпределение текущего городаВсе публичные роуты
authАвторизацияAdmin-роуты
verifiedПодтверждение emailЗащищённые действия

Правила

  • Middleware применять к группе роутов, не к каждому отдельно
  • Middleware НЕ содержит бизнес-логику — только фильтрация/подготовка request
  • Тяжёлые операции (DB-запросы) в middleware — минимизировать, кешировать

API Controllers

Коды ответов

КодКогда
200GET успешный
201POST создал ресурс
204DELETE успешный, нет тела
422Ошибка валидации (Laravel default)
429Rate limit exceeded
404Ресурс не найден
500Серверная ошибка — НЕ возвращать детали в production

Правила

  • Возвращать JSON, не HTML
  • Для сложных ответов — API Resources (трансформация модели в JSON)
  • Rate limiting (throttle) на каждый POST/PUT/DELETE endpoint
  • Не раскрывать внутренние ошибки (stack traces) в production

Anti-patterns

ПаттернПроблемаРешение
$request->validate() в контроллереВалидация не в том местеFormRequest
Больше 10 строк логики в методе контроллераFat controllerService
dd() / dump() в контроллереОстаётся в кодеЛоггер, Telescope
Прямой DB:: в контроллереОбход слоёвЧерез модель/сервис
Хардкод URL в redirectЛомается при смене роутовroute('name')
Роут без ->name()Невозможно ссылатьсяВсегда именовать
Middleware с бизнес-логикойНе то местоЛогику в Service
Один контроллер на 20+ роутовGod controllerРазбить по доменам

Внутренняя база знаний студии