Laravel中的瘦控制器

dgenwo3n  于 2023-01-31  发布在  其他
关注(0)|答案(2)|浏览(173)

我正试图通过尽可能地将代码从控制器中移走来改进我的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);
}
brccelvz

brccelvz1#

我建议不要混淆“服务”的含义。在Laravel中,Service(不是ServiceProvider,而是app文件夹中名为Services的文本文件夹)是一个允许开发人员与外部服务通信的类,它不是一个驱动某些东西的“逻辑”类,比如登录逻辑。
我所做的,在与Laravel合作了这么多年之后,是“混合”了一点DDD(领域驱动开发),我所做的只是在app中添加一个Domain文件夹,然后你把所有的逻辑都放在那里。
例如,假设我们有一个Doctors应用程序,这将是一个层级结构:

  • 应用程序
  • 控制台
  • 领域
  • 例外情况
  • HTTP协议
  • 型号
  • 提供者
  • Bootstrap
  • 配置
  • 资料库
  • 资源
  • 等等。

因此,与其在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类中。
我也采取了一种不同的方法,遵循类似于拥有“模块”的东西,所以所有的东西都在“模块”文件夹中,逻辑就在那里。我从Ryuta Hamasaki: Modularising the Monolith得到了这个想法,但这可能是更先进的方式。

byqmnocz

byqmnocz2#

您可以直接在控制器中编写验证器。因为这行代码不可能被重用。
示例:

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)
    ])
}

结束。

相关问题