内容简介:在 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 会自动捕获抛出的异常并将其转化为 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 格式错误信息:
自定义 HTTP 异常
除了 Dingo 内置支持的异常类之外,你可以创建自定义的 HTTP 异常,前提是它们继承自 Symfony\Component\HttpKernel\Exception\HttpException 基类或者实现了 Symfony\Component\HttpKernel\Exception\HttpExceptionInterface 接口。
自定义异常响应
如果你需要自定义异常返回的响应可以注册一个异常处理器(你可以在某个服务提供者如 AppServiceProvider 的 boot 方法中添加这段代码):
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\TaskController 的 store 方法如下:
public function store(CreateTaskRequest $request)
{
// 表单验证成功,继续后续处理
return $this->response->errorUnauthorized();
}
在 Postman 中访问对应的路由,如果验证失败,返回错误响应如下:
如果你想要完全实现自己的表单请求类,则必须重写 failedValidation 和 failedAuthorization 方法,这些方法必须抛出上述介绍的其中一种异常而不是 Laravel 框架抛出的 HTTP 异常,感兴趣的同学可以自己去实现下,这里就不再介绍了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Sovereign Individual
James Dale Davidson、William Rees-Mogg / Free Press / 1999-08-26 / USD 16.00
Two renowned investment advisors and authors of the bestseller The Great Reckoning bring to light both currents of disaster and the potential for prosperity and renewal in the face of radical changes ......一起来看看 《The Sovereign Individual》 这本书的介绍吧!