Если у тебя контроллер весит килобайт на пятьдесят строк, и половину из них занимают какие-то мутные вычисления, пора звать Service-классы. Они спасают от каши в коде, оставляя контроллеру только работу с HTTP-запросами. Всё, что про бизнес-логику — в сервис.
Я обычно называю это «диета для контроллеров»: выкидываешь всё жирное и тяжелое в отдельный класс, и жить сразу проще.
Шаг 1. Создаём Service-класс
В Laravel нет «официальных сервисов», но это не мешает нам сделать папку app/Services и закинуть туда, например, PostService.php.
namespace App\Services;
use App\Models\Post;
class PostService
{
public function createPost($data)
{
$post = new Post($data);
$post->save();
return $post;
}
// Тут могут быть и другие методы
}
Да, можно наворачивать интерфейсы, DI и прочую теологию, но в реальной жизни чаще всего достаточно простого класса.
Шаг 2. Используем в контроллере
Теперь контроллер выглядит не как свалка. Внедряем сервис через конструктор и пользуемся:
namespace App\Http\Controllers;
use App\Services\PostService;
use Illuminate\Http\Request;
class PostController extends Controller
{
protected $postService;
public function __construct(PostService $postService)
{
$this->postService = $postService;
}
public function store(Request $request)
{
$post = $this->postService->createPost($request->all());
return response()->json($post, 201);
}
}
Всё, контроллер похудел и занимается тем, чем должен — запросами и ответами.
Плюсы такого подхода
- Чистота кода. Контроллеры не превращаются в бог-объекты.
- Модульность. Сервис можно дергать в нескольких местах.
- Тестируемость. Тестить проще, чем если бы логика была размазана по контроллеру и модели.
Где не перегнуть палку
И вот тут часто косячат. В сервис начинают пихать всё подряд. Что туда точно не надо тащить:
- логику, связанную с самим HTTP-запросом (
Request,Response— это в контроллере); - доступ к сессиям и кукам напрямую;
- прямые SQL-запросы (сервис работает через модель или репозиторий, а не как ещё один DAL);
- авторизацию/аутентификацию (для этого есть middleware и policy);
- файловую систему напрямую (есть
Storage); - кэширование (для этого
Cache).
Service-класс — это не помойка для всего подряд. Это именно слой бизнес-логики.
Что вообще значит «бизнес-логика»?
Тут у многих, особенно у менеджеров, часто возникает ступор. Слово «бизнес» они понимают как продажи и бюджеты, «логика» — как шахматы. И когда мы говорим «бизнес-логика в коде», для них это звучит как «программист полез в бухгалтерию».
На деле всё проще: бизнес-логика — это правила, по которым работает ваш продукт в реальном мире, только записанные в коде.
Пример:
- «Скидка 10% по промокоду, но только до конца месяца и не на акционные товары».
- «Если пользователь превысил лимит, блокируем операции до оплаты».
- «Рассчитываем доставку по тарифу, зависящему от региона».
Это не про «бухгалтерию» и не про «маркетинг». Это про то, чтобы кнопка «Заказать» на сайте не превратила бизнес в минусовую кассу. Поэтому сервис-классы как раз и нужны — вынести эти правила отдельно, чтобы код был чище, тестируемее и проще менять, когда бизнес передумает (а он передумает всегда).
Итог
Service-классы в Laravel — это про порядок. Если у тебя контроллер напоминает сценарий к индийскому фильму с сотней событий за пять минут, то пора резать лишнее и выносить в сервис. Но не превращай сервисы в новый монолит — иначе будешь разгребать тот же бардак, только в другом месте.
0 комментариев