换种方式使用 Laravel 的 request 验证
之前在公司一直拿着laravel这个全栈框架当做api框架使用,为什么不用lumen,可能是任性吧。长期使用中对laravel进行了大量的二次改写 ,这里分享一下另外一种request的验证使用,让request的使用更加适用于前后端分离json交互的后端项目,分享给社区的朋友。
请指点。
laravel的request验证都是交给异常去处理的,所以这里我新建了一个处理except的类
php artisan make:exception ApiRequestExcept
ApiRequestExcept.php代码如下
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Http\Request;
class ApiRequestExcept extends Exception
{
/**
* @var int http status code
*/
protected $statusCode;
public function __construct($message = "", $code = 0, $statusCode = 500)
{
$this->statusCode = $statusCode;
parent::__construct($message, $code);
}
public function render(Request $request)
{
return response([
'code' => $this->code,
'msg' => $this->message
])->setStatusCode($this->statusCode);
}
}
然后我们在新建一个request,并且改写
php artisan make:request ApiBaseRequest
ApiBaseRequest.php代码如下
<?php
namespace App\Http\Requests;
use App\Exceptions\ApiRequestExcept;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
class ApiBaseRequest extends FormRequest
{
/**
* 程序自定义业务错误码
*
* @var int
*/
protected $code = 0;
/**
* http状态码
*
* @var int
*/
protected $statusCode = 500;
/**
* Determine if the user is authorized to make this request. * * @return bool
*/
public function authorize()
{
return true;
}
/**
* @param Validator $validator
*
* @throws ApiRequestExcept
*/
protected function failedValidation(Validator $validator)
{
throw new ApiRequestExcept(
$validator->errors()->first(),
$this->code,
$this->statusCode
);
}
}
这个request是需要其他request继承的基类,现在我们试试效果。
我们新建一个UserRequest,然后继承ApiBaseRequest这个文件
php artisan make:request UserRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserRequest extends ApiBaseRequest
{
public function rules()
{
return [
'name' => 'required'
];
}
public function messages()
{
return [
'name.required' => '请先填写名字'
];
}
}
然后在控制器中使用这个UserRequest
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UserRequest;
class RequestController extends Controller
{
public function user(UserRequest $request)
{
return [
'code' => 200,
'msg' => '通过测试',
'name' => $request->name
];
}
}
在没有填写name字段的时候,就会有这个响应
现在把name字段加入,就正常通过了
然后自定义的code和http的statuscode是直接在UserRequest中写就可以的,非常方便
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserRequest extends ApiBaseRequest
{
protected $code = -1;
protected $statusCode = 400;
public function rules()
{
return [
'name' => 'required'
];
}
public function messages()
{
return [
'name.required' => '请先填写名字'
];
}
}
然后把name字段取消再试一次
可以看到业务码和http的statuscode都变了。
如果每次都去修改新建的request代码有点麻烦,那么简单的做法就是我们重写一下artisan make的命令
php artisan make:command RequestMakeCommand
把RequestMakeCommand文件改成如下
<?php
namespace App\Console\Commands;
//use Illuminate\Console\Command;
use Illuminate\Foundation\Console\RequestMakeCommand as Command;
class RequestMakeCommand extends Command
{
protected function getStub()
{
return __DIR__.'/stubs/request.stub';
}
}
这个request.stub是自己建的,文件结构如下图
这是request.stub的内容,如下
<?php
namespace DummyNamespace;
class DummyClass extends ApiBaseRequest
{
public function rules()
{
return [
];
}
public function messages()
{
return [
];
}
}
现在就可以了,让我们再试一试
php artisan make:request EditRequest
我们会发现通过命令你行建的request文件符合改造,如下
<?php
namespace App\Http\Requests;
class EditRequest extends ApiBaseRequest
{
public function rules()
{
return [
'age' => 'numeric'
];
}
public function messages()
{
return [
'age.numeric' => '年龄必须是数字'
];
}
}
rules方法和message方法里面的代码是我自己添加上去的,然后测试一下。
好了,搞定。
如此改造了之后的request让我们开发更加愉悦了,而且改动的也很轻量,让后端使用起来更加得心应手。如果有帮助到正在看的你,请点个赞。如果你有更好的看法,请指点。技术多交流,社区和大家才会变的越来越棒。
最后,武汉加油!!!
疫情结束后,我还要回成都找工作。
本作品采用《CC 协议》,转载必须注明作者和本文链接
所以 REST 不香了?
这个是分层设计的模式!让程序更清晰!专为API设计的
哈哈哈 我最爱这样
其实不用这么麻烦的,表单验证错误抛出的异常都是同一个异常。

可以在
Laravel
的异常处理App\Exceptions\Handler
里面进行捕获,然后统一处理的。