Laravel по FSD, пример AuthController

от автора

в
Время чтения: 4 мин.

В рамках предложенной структуры, AuthController будет находиться в директории features/Auth/Http/Controllers/. Этот контроллер будет отвечать за обработку HTTP-запросов, связанных с аутентификацией (например, регистрация, вход, выход).

Пример реализации AuthController:

<?php

namespace App\Features\Auth\Http\Controllers;

use App\Features\Auth\Actions\RegisterUserAction;
use App\Features\Auth\Data\RegisterUserData;
use App\Features\Auth\Http\Requests\RegisterRequest;
use App\Features\Auth\Http\Resources\UserResource;
use App\Features\Auth\Services\AuthService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class AuthController
{
    public function __construct(
        private readonly AuthService $authService,
        private readonly RegisterUserAction $registerUserAction,
    ) {}

    /**
     * Регистрация нового пользователя.
     */
    public function register(RegisterRequest $request): JsonResponse
    {
        // Создаем DTO из запроса
        $registerUserData = RegisterUserData::fromRequest($request);

        // Выполняем действие регистрации
        $user = $this->registerUserAction->execute($registerUserData);

        // Возвращаем ответ с ресурсом пользователя
        return response()->json([
            'user' => new UserResource($user),
            'token' => $this->authService->createToken($user),
        ], 201);
    }

    /**
     * Вход пользователя в систему.
     */
    public function login(Request $request): JsonResponse
    {
        $credentials = $request->only('email', 'password');

        // Аутентификация пользователя
        $user = $this->authService->attemptLogin($credentials);

        if (!$user) {
            return response()->json(['message' => 'Invalid credentials'], 401);
        }

        // Возвращаем ответ с токеном
        return response()->json([
            'user' => new UserResource($user),
            'token' => $this->authService->createToken($user),
        ]);
    }

    /**
     * Выход пользователя из системы.
     */
    public function logout(Request $request): JsonResponse
    {
        // Удаление токена
        $this->authService->revokeToken($request->user());

        return response()->json(['message' => 'Logged out successfully']);
    }
}

Описание компонентов, используемых в AuthController:

  1. RegisterRequest:
  • Находится в features/Auth/Http/Requests/.
  • Отвечает за валидацию данных запроса на регистрацию. Пример:
   <?php

   namespace App\Features\Auth\Http\Requests;

   use Illuminate\Foundation\Http\FormRequest;

   class RegisterRequest extends FormRequest
   {
       public function rules(): array
       {
           return [
               'name' => ['required', 'string', 'max:255'],
               'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
               'password' => ['required', 'string', 'min:8', 'confirmed'],
           ];
       }
   }
  1. RegisterUserData:
  • Находится в features/Auth/Data/.
  • Это DTO (Data Transfer Object), который используется для передачи данных между слоями. Пример:
   <?php

   namespace App\Features\Auth\Data;

   use App\Features\Auth\Http\Requests\RegisterRequest;

   class RegisterUserData
   {
       public function __construct(
           public readonly string $name,
           public readonly string $email,
           public readonly string $password,
       ) {}

       public static function fromRequest(RegisterRequest $request): self
       {
           return new self(
               name: $request->input('name'),
               email: $request->input('email'),
               password: $request->input('password'),
           );
       }
   }
  1. RegisterUserAction:
  • Находится в features/Auth/Actions/.
  • Отвечает за выполнение бизнес-логики регистрации. Пример:
   <?php

   namespace App\Features\Auth\Actions;

   use App\Features\Auth\Data\RegisterUserData;
   use App\Features\Auth\Models\User;
   use App\Features\Auth\Repositories\UserRepository;

   class RegisterUserAction
   {
       public function __construct(
           private readonly UserRepository $userRepository,
       ) {}

       public function execute(RegisterUserData $data): User
       {
           return $this->userRepository->create([
               'name' => $data->name,
               'email' => $data->email,
               'password' => bcrypt($data->password),
           ]);
       }
   }
  1. AuthService:
  • Находится в features/Auth/Services/.
  • Отвечает за логику, связанную с аутентификацией (например, создание токенов). Пример:
   <?php

   namespace App\Features\Auth\Services;

   use App\Features\Auth\Models\User;
   use Illuminate\Support\Facades\Hash;
   use Laravel\Sanctum\NewAccessToken;

   class AuthService
   {
       public function attemptLogin(array $credentials): ?User
       {
           $user = User::where('email', $credentials['email'])->first();

           if (!$user || !Hash::check($credentials['password'], $user->password)) {
               return null;
           }

           return $user;
       }

       public function createToken(User $user): NewAccessToken
       {
           return $user->createToken('auth-token');
       }

       public function revokeToken(User $user): void
       {
           $user->currentAccessToken()->delete();
       }
   }
  1. UserResource:
  • Находится в features/Auth/Http/Resources/.
  • Используется для преобразования модели пользователя в JSON. Пример:
   <?php

   namespace App\Features\Auth\Http\Resources;

   use Illuminate\Http\Resources\Json\JsonResource;

   class UserResource extends JsonResource
   {
       public function toArray($request): array
       {
           return [
               'id' => $this->id,
               'name' => $this->name,
               'email' => $this->email,
           ];
       }
   }

Маршруты для AuthController:

Маршруты можно определить в infrastructure/Routes/auth.php:

<?php

use App\Features\Auth\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', [AuthController::class, 'logout'])->middleware('auth:sanctum');

Затем подключить этот файл в основном routes/api.php:

<?php

use Illuminate\Support\Facades\Route;

Route::prefix('auth')->group(base_path('infrastructure/Routes/auth.php'));

Итог:

  • Контроллер AuthController отвечает только за обработку HTTP-запросов.
  • Вся бизнес-логика вынесена в сервисы и действия.
  • Данные передаются через DTO.
  • Код организован в соответствии с принципами Feature Sliced Design, что делает его модульным и легко поддерживаемым.

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Сколько будет 7 + 4?