[英]Skinny Controllers in Laravel
I am trying to improve my Laravel code design by moving code away from the controllers as much as possible.我正在尝试通过将代码尽可能远离控制器来改进我的 Laravel 代码设计。
In my AuthController
I have a store
function for logging in the user, where can I move the logic in this function?在我的
AuthController
,我有一个store
function 用于登录用户,我可以在哪里移动这个 function 中的逻辑?
So far I have implemented a FormRequest
for validation and UserResource
for the response fields.到目前为止,我已经实现了用于验证的
FormRequest
和用于响应字段的UserResource
。 I was thinking of creating a file in /Services
called AuthService
and moving authentication logic there, unless there is a better design pattern?我正在考虑在
/Services
中创建一个名为AuthService
的文件并在那里移动身份验证逻辑,除非有更好的设计模式? Or maybe logic for authentication can be moved to the User
's model?或者可以将身份验证逻辑移至
User
的 model?
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);
}
I would recommend to never mixup what a "service" is/means.我建议永远不要混淆“服务”是什么/意味着什么。 In Laravel a
Service
(not a ServiceProvider
, but a literal folder called Services
in the app
folder) is a class that allows the developer to communicate with external services, it is not a "logic" class that drives something, like logic for logging in.在 Laravel 中,
Service
(不是ServiceProvider
,而是app
文件夹中名为Services
的文字文件夹)是一个 class ,它允许开发人员与外部服务进行通信,它不是驱动某些东西的“逻辑” class ,例如用于登录的逻辑.
What I have done, after working so many years with Laravel, is to "mix" a little bit of DDD (Domain Driven Development), what I have done is just add a Domain
folder inside app
, and you put ALL your logic in there.在与 Laravel 合作多年后,我所做的就是“混合”一点 DDD(领域驱动开发),我所做的只是在
app
中添加一个Domain
文件夹,然后将所有逻辑放入其中.
For example, imagine we have a Doctors app, this would be the heriarchy:例如,假设我们有一个 Doctors 应用程序,这将是层次结构:
So, intead of having stuff inside a app/Services
, just put code inside Domain
, like this (following our example):因此,不要将内容放在
app/Services
中,只需将代码放在Domain
中,就像这样(按照我们的示例):
App\Domain\Common
)App\Domain\Common
)
App\Domain\Doctor
)App\Domain\Doctor
)App\Domain\Facility
)App\Domain\Facility
)App\Domain\Patient
)App\Domain\Patient
) So, the idea is to put true logic inside this Domain
folder (and further organize them), so you can then NOT mix logic or stuff togheter.所以,我们的想法是将真正的逻辑放在这个
Domain
文件夹中(并进一步组织它们),这样你就不能将逻辑或东西混合在一起。
To wrap it up, you would then have controllers like this:总结一下,您将拥有这样的控制器:
class PatientController extends Controller
{
public function store(PatientRequest $request)
{
return \App\Domain\Patient\Entity::store(
$request->input('name'),
$request->input('email'),
$request->input('age')
);
}
}
All the logic for "registering" (manipulating something from the Patient) model, is on the Entity
class. “注册”的所有逻辑(从患者那里操作一些东西)model,都在
Entity
class 上。
I have also taken a different approach by following something similar to having "modules", so everything is in a "modules" folder and that logic is just in there.我还采取了一种不同的方法,遵循类似于拥有“模块”的方法,因此所有内容都在“模块”文件夹中,逻辑就在那里。 I got that idea from Ryuta Hamasaki: Modularising the Monolith , but this may be way more advance.
我从Ryuta Hamasaki 那里得到了这个想法:Modularising the Monolith ,但这可能更先进。
You can write the validator directly in the controller. Because this line of code has no possibility of being reused.验证器可以直接写在controller。因为这行代码没有被复用的可能。
Example:例子:
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)
])
}
End.结尾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.