一种处理laravel返回值响应的解决方案

前言

并且让你的错误信息更适合摸鱼的你 :laughing:

返回值的几种情况

返回值一般有以下几种情况:

  1. 返回正确的数据, 指的是接口正确返回了请求期望的数据。
  2. 返回异常,指的是由于一些预料之中的原因,接口没能返回数据,这种情况返回的是一个异常信息,常见的一些可能导致异常的原因有:
    • 传入的数据不符合规则
    • 没有登录认证
    • 没有权限
    • 请求的资源不存在
    • url 不正确
  3. 返回错误, 指的是由于一些预料之外的原因,接口没能返回数据。 比如代码跑的跑的出bug了等等

响应格式

首先, 我们定义返回值的响应格式, 当请求成功时,我们返回 code message data 三个字段, 当请求出现异常和错误时我们返回 code message error 三个字段。

这里的 codehttp 状态码, error 是具体的错误信息。比如很多公司有一套错误代码, 这个错误代码会在这个 error 中。

class ResponseUtil{
    static function success($code=200$message='请求成功!'$data=[]){
        return response()->json([
            'code' => $code,
            'message' => $message,
            'data' => $data
        ]);
    }

    static function error($code=500, $message='请求失败!'$error=[])
    {
        return response()->json([
            'code' => $code,
            'message' => $message,
            'error' => $error
        ]);
    }
}

然后我们说明一下上面的内些情况具体返回内些数据。

返回正确的数据。

直接在控制器里像下面这样写。

// 这里使用了 php8 的命名参数
ResponseUtil::success(data: $data)

返回异常

传入的数据不符合规则

这种情况需要我们写表单验证类,使用表单验证类对传入数据进行验证,如果不正确的话抛出异常。

php artisan make:requests

为了让表单验证类抛出我们想要的异常使得异常处理时能返回我们预先定义好格式的数据。我们需要对生成的表单验证类做一些修改

use \Illuminate\Contracts\Validation\Validator;
// 这里自定义一个表单验证不通过异常
use \My\ValidationException;
class MyRequest extends FormRequest{
        ···
        protected function failedValidation(Validator $validator)
        {
            // 当验证不通过时,抛出自定义的表单异常类
            // 这里的 $validator->errors() 的值可以自己打印看看, 这里可以写一些逻辑判断, 然后用自己的错误信息替换这个 error 信息,比如用户名不正确错误码 400001 之类的
            throw new ValidationException($validator->errors());
        }
}

我们需要自定义一个表单验证异常类, 在这个异常类中实现 render 方法, render 负责向客户端返回数据

class ValidationException extends Exception
{
        public function render(): \Illuminate\Http\JsonResponse
        {
            // 当发生表单验证不通过异常时,按照下面的方式返回异常
            return RespondUtil::errorRespond(401, '参数缺失', $this->getMessage());
        }
}

最后在控制器注入表单验证类即可。理论上来说,只要每个接受输入的接口都使用表单验证类,并且精心设计好验证规则,应该就不会出现输入不正确导致错误,但是返回的信息不是表单验证不通过的问题了。

没有登录认证

我们一般判断这个请求有没有登录认证都是通过 auth 中间件。这种情况我们只要修改一下
App\Http\MiddlewareAuthenticate 即可.

namespace App\Http\Middleware;
// 这里自定义一个认证不通过异常
use \My\AuthenticationException;
class Authenticate extends Middleware
{
            protected function unauthenticated($request, array $guards)
            {
                // 当登录失效时,抛出自定义的认证不通过异常
                throw new AuthenticationException('登录失效');
            }
}

自定义的认证不通过类

class AuthenticationException extends Exception
{
            public function render(): \Illuminate\Http\JsonResponse
            {
                return RespondUtil::errorRespond(401, '认证失败', $this->getMessage());
            }
}

没有权限和请求的资源不存在

它俩可以在表单验证类或者控制器中手动抛出自定义异常。

url 不正确

直接在路由文件里面加一个 fallback 路由,然后在路由中直接返回或者抛出自定义异常 路由《Laravel 10 中文文档》

返回错误

我们知道, 在发生没有被捕获的异常或者错误后,laravel 框架的错误处理会用使用 App\Exceptions\Handler 进行处理。我们只要在 Handlerregister 一个 renderable 像下面内样

public function register ()
{
        $this->renderable(function(\Throwable $e){
            return RespondUtil::errorRespond(500, '发生意料之外的错误'$e->getMessage());
        });
}

只要错误能被框架捕获, 它就会返回我们指定的错误信息。
返回 500 不是结束,500 debug 的开始。

“不可能吧,在我这里没问题呀?”;
“不可能吧,你传的参数都没问题吗?”
“不可能吧,你环境有问题吧?”
“我X,我写的程序怎么会有bug?”

这篇文章参考了 翻译:Laravel API 错误处理:当异常时,如何返回消息 的思路,示例代码仅供参考,如果有不合理之处也欢迎指正, 感谢!

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 4
陈先生

:see_no_evil: 之前忙里偷闲写了个,我觉得你可以将其完善一下。

learnku.com/users/23921/articles

9个月前 评论
徵羽宫 (楼主) 9个月前
陈先生 (作者) 9个月前
徵羽宫 (楼主) 9个月前

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