Тонкие контроллеры в Laravel

Я пытаюсь улучшить свой дизайн кода Laravel, максимально удаляя код от контроллеров.

У меня в AuthController есть функция store для входа пользователя, куда переместить логику в этой функции?

До сих пор я реализовал FormRequest для проверки и UserResource для полей ответа. Я думал создать файл в /Services с именем AuthService и перенести туда логику аутентификации, если нет лучшего шаблона проектирования? Или, может быть, логику аутентификации можно перенести в модель User?

public function store(StoreAuthRequest $request)
{
    $user = User::where('email', $request->input('email'))->first();

    if (!$user || !Hash::check($request->input('password'), $user->password)) {
        return response([
            'message' => 'Bad credentials'
        ], 401);
    }

    $token = $user->createToken('AppToken')->plainTextToken;

    return response([
        'user' => new UserResource($user),
        'token' => $token
    ], 201);
}

лучше не перемещать какую-либо системную логику в модель, у вас есть другой класс опций для этого, например, класс обслуживания (несколько) или класс действий (одиночный)

Win 29.01.2023 18:28

кстати, если вы уже стерилизовали свой запрос с помощью StoreAuthRequest, лучше не использовать $request->input снова, вместо этого используйте $request->validated() или $request->safe()

Win 29.01.2023 18:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете написать валидатор прямо в контроллере. Потому что эта строка кода не имеет возможности повторного использования.

Пример:

public function store(Request $request)
{
    $request->validate([
        'email' => ['required', 'email'],
        'password' => ['required'],
    ]);
    $user = User::query()
        ->where('email', $request->email)
        ->first();
    // PHP 8.x
    if (! Hash::check($request->password, $user?->password)) {
        // Throw an exception
    }
    
    return response()->json([
        'token' => $user->createToken(...)->plainTextToken,
        'user' => new UserResource($user), // or UserResource::make($user)
    ])
}

Конец.

Я думаю, вы идете в противоположном направлении, которое хотел ОП. Перемещение проверки в контроллер делает контроллер толще.

ceejayoz 29.01.2023 17:49

@ceejayoz В общем, рекомендуется ставить валидатор в Запрос. Но слишком большая инкапсуляция в сценарии входа сделает код более трудным для понимания.

Tall Libra 30.01.2023 08:03
Ответ принят как подходящий

Я бы порекомендовал никогда не путать, что такое «сервис». В Laravel Service (не ServiceProvider, а буквальная папка с именем Services в папке app) — это класс, который позволяет разработчику общаться с внешними службами, это не «логический» класс, который управляет чем-то, например, логикой для входа в систему. .

Что я сделал после стольких лет работы с Laravel, так это немного «подмешал» DDD (Domain Driven Development), что я сделал, так это просто добавил папку Domain внутрь app, и вы поместили туда ВСЮ свою логику. .

Например, представьте, что у нас есть приложение «Врачи», это будет иерархия:

  • приложение
    • Консоль
    • Домен
    • Исключения
    • http
    • Модели
    • Провайдеры
  • начальная загрузка
  • конфигурация
  • база данных
  • Ресурсы
  • и т. д.

Итак, вместо того, чтобы помещать что-то внутри app/Services, просто поместите код внутри Domain, вот так (следуя нашему примеру):

  • Домен
    • Общий (App\Domain\Common)
      • перечисления
      • События
      • Слушатели
      • Работа
      • Услуги
    • Доктор (App\Domain\Doctor)
    • Объект (App\Domain\Facility)
    • Пациент (App\Domain\Patient)

Итак, идея состоит в том, чтобы поместить настоящую логику в эту папку Domain (и дополнительно их организовать), чтобы вы НЕ могли смешивать логику или что-то еще вместе.

Чтобы завершить это, у вас будут такие контроллеры:

class PatientController extends Controller
{
    public function store(PatientRequest $request)
    {
        return \App\Domain\Patient\Entity::store(
            $request->input('name'),
            $request->input('email'),
            $request->input('age')
        );
    }
}

Вся логика для «регистрации» (манипулирования чем-либо из модели «Пациент») находится в классе Entity.


Я также использовал другой подход, следуя чему-то похожему на наличие «модулей», поэтому все находится в папке «модули», и эта логика просто там. Я получил эту идею от Рюты Хамасаки: Модульность монолита, но это может быть намного более продвинутым.

Другие вопросы по теме