Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке «товстий контролер» у Laravel і куди переносити логіку?

Товстий контролер - метод контролера на сотню рядків, де змішано все: валідацію, перевірку прав, бізнес-правила, роботу з базою, відправку листів, виклики сторонніх API, формування відповіді.

public function store(Request $request)
{
    $request->validate([...]);                        // валідація
    if ($request->user()->orders()->count() > 10) {}  // бізнес-правило
    $order = Order::create([...]);                    // збереження
    foreach ($request->items as $item) { /* ... */ }  // розрахунки
    Mail::to($request->user())->send(new OrderPlaced($order));
    Http::post('https://crm.example/api/...', [...]); // інтеграція
    return response()->json(...);
}

Чому це погано: логіку неможливо перевикористати (з команди Artisan, черги, API й адмінки потрібна та сама дія), важко тестувати окремо від HTTP, кожна зміна чіпає великий метод.

Що куди переносити:

Що Куди
валідація й авторизація запиту Form Request (rules(), authorize())
права на конкретні об'єкти політики ($this->authorize('update', $order))
бізнес-операція action-клас чи сервіс (PlaceOrder)
реакції на подію (листи, інтеграції) події й слухачі, часто в черзі
довгі чи ненадійні операції джоби в черзі
форматування відповіді API Resource, view
запити, що повторюються scopes моделі, query-класи

Після рефакторингу контролер - тонкий координатор:

public function store(StoreOrderRequest $request, PlaceOrder $placeOrder)
{
    $order = $placeOrder->handle($request->user(), $request->validated());

    return OrderResource::make($order)->response()->setStatusCode(201);
}

Він знає лише про HTTP: отримати перевірений запит, викликати дію, повернути відповідь.

Не варто впадати в іншу крайність: для простого CRUD без бізнес-логіки Post::create($request->validated()) у контролері - цілком нормально. Окремий клас на кожен рядок коду - теж складність. Виносити варто, коли з'являється реальна логіка або потреба викликати ту саму дію з кількох місць.

Докладніше в документації: Laravel: контролери

1

Схожі питання