之前在公司一直拿著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 協議》,轉載必須註明作者和本文連結