使用 Dingo API 扩展包快速构建 Laravel RESTful API(七) —— 错误及异常处理

栏目: PHP · 发布时间: 5年前

内容简介:在 Dingo API 中,你可以使用响应构建器支持的多种错误方法生成错误响应:在构建 API 的时候处理异常是一件痛苦的事,在 Dingo API 中,你不需要手动构建异常响应,只需要抛出一个继承自下面是 Dingo API 内置的 Symfony 异常:

错误响应

在 Dingo API 中,你可以使用响应构建器支持的多种错误方法生成错误响应:

// 通用的错误响应,包含错误消息和状态码
return $this->response->error('404 Not Found', 404);

// 返回 404 Not Found 响应,等同于上述返回 404 状态码的错误响应
return $this->response->errorNotFound();

// 返回 401 Bad Request 响应,等同于调用 error('Bad Request', 401) 
return $this->response->errorBadRequest();

// 返回 403 Forbidden 响应,等同于调用 error('Forbidden', 403)
return $this->response->errorForbidden();

// 返回 500 Internal Error 响应,等同于调用 error('Internal Error', 500)
return $this->response->errorInternal();

// 返回 401 Unauthorized 响应,等同于调用 error('Unauthorized', 401)
return $this->response->errorUnauthorized();

// 返回 405 Method Not Allowed 响应,比如在 GET 路由上发起 POST 请求就会报这个错
return $this->response->errorMethodNotAllowed();

异常处理

异常响应

在构建 API 的时候处理异常是一件痛苦的事,在 Dingo API 中,你不需要手动构建异常响应,只需要抛出一个继承自 Symfony\Component\HttpKernel\Exception\HttpException 的异常,Dingo API 就会自动为你处理这个响应。

下面是 Dingo API 内置的 Symfony 异常:

异常 状态码
Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException 403
Symfony\Component\HttpKernel\Exception\BadRequestHttpException 400
Symfony\Component\HttpKernel\Exception\ConflictHttpException 409
Symfony\Component\HttpKernel\Exception\GoneHttpException 410
Symfony\Component\HttpKernel\Exception\HttpException 500
Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException 411
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException 405
Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException 406
Symfony\Component\HttpKernel\Exception\NotFoundHttpException 404
Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException 412
Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException 428
Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException 503
Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException 429
Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException 401
Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException 415

下面是一个示例,当我们尝试更新一条已经被别人更新过的记录时抛出一个 ConflictHttpException 异常:

$api->version('v1', function ($api) {
    $api->put('task/{id}', function ($id) {
        $task = \App\Task::find($id);

        if ($task->updated_at > app('request')->get('last_updated')) {
            throw new \Symfony\Component\HttpKernel\Exception\ConflictHttpException('Task was updated prior to your request.');
        }

        // No error, we can continue to update the user as per usual.
    });
});

我们在 Postman 中模拟发起这个 PUT 请求,并设置 last_updated 字段为小于指定任务最后更新时间的值,Dingo API 就会返回一个错误响应:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(七) —— 错误及异常处理

Dingo API 会自动捕获抛出的异常并将其转化为 JSON 格式,响应的 HTTP 状态码也会相应更改以匹配这个异常, ConflictHttpException 对应的 HTTP 状态码是 409。

资源异常

以下是资源异常,每个异常都会返回 422 状态码:

Dingo\Api\Exception\DeleteResourceFailedException
Dingo\Api\Exception\ResourceException
Dingo\Api\Exception\StoreResourceFailedException
Dingo\Api\Exception\UpdateResourceFailedException

这些异常的特殊之处在于你可以将创建、更新或者删除资源时遇到的验证错误传递到这些异常中。

下面我们就来看一个创建新用户验证失败抛出 StoreResourceFailedException 异常的例子:

$api->version('v1', function ($api) {
    $api->post('tasks', function () {
        $rules = [
            'text' => ['required', 'string'],
            'is_completed' => ['required', 'boolean']
        ];

        $payload = app('request')->only('text', 'is_completed');

        $validator = app('validator')->make($payload, $rules);

        if ($validator->fails()) {
            throw new \Dingo\Api\Exception\StoreResourceFailedException('Could not create new task.', $validator->errors());
        }

        // Create user as per usual.
    });
});

Dingo API 会自动捕获抛出的异常并将其转化为 JSON 格式,响应的 HTTP 状态码也会更改为与异常相匹配的值,资源异常会返回 422 状态码以及如下 JSON 格式错误信息:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(七) —— 错误及异常处理

自定义 HTTP 异常

除了 Dingo 内置支持的异常类之外,你可以创建自定义的 HTTP 异常,前提是它们继承自 Symfony\Component\HttpKernel\Exception\HttpException 基类或者实现了 Symfony\Component\HttpKernel\Exception\HttpExceptionInterface 接口。

自定义异常响应

如果你需要自定义异常返回的响应可以注册一个异常处理器(你可以在某个服务提供者如 AppServiceProviderboot 方法中添加这段代码):

app(\Dingo\Api\Exception\Handler::class)->register(function (\Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException $exception) {
    return \Illuminate\Support\Facades\Response::make(['error' => 'Hey, what do you think you are doing!?'], 401);
});

现在如果认证失败(抛出 UnauthorizedHttpException 异常)就会返回如下 JSON 格式信息:

{
    "error": "Hey, what do you think you are doing!?"
}

表单请求类

如果你要使用表单请求类,那么需要继承 Dingo API 表单请求基类 Dingo\Api\Http\FormRequest 或者完全自己实现。表单请求类会检查输入请求是否是针对当前 API 的,如果是的话,当验证失败会抛出 Dingo\Api\Exception\ValidationHttpException 异常。这个异常会被 Dingo API 渲染并返回相应的错误响应。

下面我们在 app/Http/Requests 目录下创建一个继承自 Dingo API 请求基类的表单请求类 CreateTaskRequest ,并编写其实现代码如下:

<?php

namespace App\Http\Requests;

use Dingo\Api\Http\FormRequest;

class CreateTaskRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'text' => 'required|string',
            'is_completed' => 'required|boolean'
        ];
    }
}

这样一来,我们就可以在控制器方法中声明这个表单请求类来进行表单字段验证了,编写 Api\TaskControllerstore 方法如下:

public function store(CreateTaskRequest $request)
{
    // 表单验证成功,继续后续处理
    return $this->response->errorUnauthorized();
}

在 Postman 中访问对应的路由,如果验证失败,返回错误响应如下:

使用 Dingo API 扩展包快速构建 Laravel RESTful API(七) —— 错误及异常处理

如果你想要完全实现自己的表单请求类,则必须重写 failedValidationfailedAuthorization 方法,这些方法必须抛出上述介绍的其中一种异常而不是 Laravel 框架抛出的 HTTP 异常,感兴趣的同学可以自己去实现下,这里就不再介绍了。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

小群效应

小群效应

徐志斌 / 中信出版集团 / 2017-11 / 58.00元

互联网经济时代,新零售、网红经济、知识经济多受益于社群。用户的获取、留存及订单转化直接决定了一个社群的存亡。无论是“做”群还是“用”群,每个人都需要迭代常识:了解用户行为习惯,了解社群运行规律。 《社交红利》《即时引爆》作者徐志斌历时两年,挖掘腾讯、百度、豆瓣的一手后台数据,从上百个产品中深度解读社群行为,通过大量生动案例总结出利用社交网络和海量用户进行沟通的方法论。 本书将告诉你: ......一起来看看 《小群效应》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换