换种方式使用 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 字段的时候,就会有这个响应

换种方式使用laravel的request验证

现在把 name 字段加入,就正常通过了

换种方式使用laravel的request验证

然后自定义的 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 字段取消再试一次

换种方式使用laravel的request验证

可以看到业务码和 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 是自己建的,文件结构如下图

换种方式使用laravel的request验证

这是 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 方法里面的代码是我自己添加上去的,然后测试一下。

换种方式使用laravel的request验证

好了,搞定。

如此改造了之后的 request 让我们开发更加愉悦了,而且改动的也很轻量,让后端使用起来更加得心应手。如果有帮助到正在看的你,请点个赞。如果你有更好的看法,请指点。技术多交流,社区和大家才会变的越来越棒。

最后,武汉加油!!!
疫情结束后,我还要回成都找工作。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 4
medz

所以 REST 不香了?

5年前 评论
L学习不停 (楼主) 5年前
medz (作者) 5年前
L学习不停 (楼主) 5年前

这个是分层设计的模式!让程序更清晰!专为 API 设计的

5年前 评论

哈哈哈 我最爱这样

5年前 评论

其实不用这么麻烦的,表单验证错误抛出的异常都是同一个异常。
可以在 Laravel 的异常处理 App\Exceptions\Handler 里面进行捕获,然后统一处理的。
file

5年前 评论
L学习不停 (楼主) 5年前
道法自然 5年前
韩槑槑 (作者) 5年前
lyxxxh 4年前
xiangxihenli 4年前