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

所以 REST 不香了?

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

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

4年前 评论

哈哈哈 我最爱这样

4年前 评论

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

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

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!