Чистая архитектура в Laravel: как писать масштабируемые проекты

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

📁 1. Разделяй слои: контроллеры — не мусорка

Контроллер не должен содержать бизнес-логику. Его задача — принять запрос, передать данные дальше и вернуть ответ. Пример плохо:

public function store(Request $request)
{
  $user = User::create([
    'name' => $request->name,
    'email' => $request->email,
  ]);

  Mail::to($user->email)->send(new WelcomeMail($user));

  return redirect()->back();
}
Пример лучше:

public function store(StoreUserRequest $request)
{
  $this->userService->createUser($request->validated());
  return back();
}

⚙️ 2. Используй слои: Service, Action, DTO

- Service — общая бизнес-логика - Action — конкретное действие (например, CreateUserAction) - DTO (Data Transfer Object) — объект для передачи данных Пример DTO:

class CreateUserDTO
{
  public function __construct(
    public string $name,
    public string $email,
  ) {}
}
И ты передаёшь его вот так:

$dto = new CreateUserDTO(
  name: $request->name,
  email: $request->email,
);

$this->createUserAction->handle($dto);

📚 3. Храни бизнес-логику вне моделей

Eloquent-модели хороши, но не надо превращать их в мусорные ведра с кучей методов. Плохо:

class User extends Model
{
  public function sendWelcomeMail()
  {
    Mail::to($this->email)->send(new WelcomeMail($this));
  }
}
Лучше: Вынеси это в отдельный MailService или Action.

🔁 4. Валидация — через Form Request

Не пиши в контроллере if ($request->has(...)). Используй php artisan make:request — и вся валидация будет в одном месте.

class StorePostRequest extends FormRequest
{
  public function rules(): array
  {
    return [
      'title' => 'required|string|max:255',
      'body' => 'required|string',
    ];
  }
}

🧪 5. Думай о тестах с самого начала

Когда логика разбита по слоям (Actions, Services), писать тесты — одно удовольствие.

it('creates user', function () {
  $dto = new CreateUserDTO('Test', 'test@mail.com');
  $user = app(CreateUserAction::class)->handle($dto);

  expect($user)->toBeInstanceOf(User::class);
});

📦 6. Структура проекта

Вот пример структуры без перегруза:

app/
├── Actions/
├── DTOs/
├── Http/
│ ├── Controllers/
│ └── Requests/
├── Models/
├── Services/
├── ViewModels/
Такой порядок легко читать, и по названию файлов понятно, что где лежит.

🔚 Вывод

Чистая архитектура — это не модная тема для конференций. Это здравый смысл. Пиши так, чтобы самому не было больно поддерживать проект через полгода. Делай код читаемым, логичным и разбитым на понятные куски. Laravel это позволяет — бери и делай.

7.07.2025

4
A B i U S JS

PHP HTML CSS
Чат
    Для входа только имэйл или имя и апроль
    Можно сменить аватар
    Имэйл Ваше имя
    Пароль