phpro/api-problem
Composer 安装命令:
composer require phpro/api-problem
包简介
RFC7807 Problem details implementation
README 文档
README
Api Problem
This package provides a RFC7807 Problem details implementation. It can be integrated everywhere in your code and should result in a general error response format for HTTP APis.
This package only provides a generic interface, an exception class and some built-in api problem messages. Since handling the exceptions is up to the framework, here is a list of known framework integrations:
- Symfony
^4.1: ApiProblemBundle
Installation
composer require phpro/api-problem
Usage
This package provides a general interface for creating ApiProblem value objects.
use Phpro\ApiProblem\Exception; throw new ApiProblemException( new HttpApiProblem(418, ['detail' => 'Did you know 4,000 people are injured by teapots every year?!']) );
Built-in problems
-
General problems
-
Symfony integration problems
-
Http problems
ExceptionApiProblem
Debuggable: The exception part will only be added in debug context!
use Phpro\ApiProblem\Http\ExceptionApiProblem; new ExceptionApiProblem(new \Exception('message', 500));
{
"status": 500,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Internal Server Error",
"detail": "message",
"exception": {
"message": "message",
"type": "RuntimeException",
"code": 500,
"line": 23,
"file": "exception.php",
"trace": [
"#0 [internal function]: ...",
"#1 [internal function]: ...",
"#3 [internal function]: ...",
"..."
],
"previous": [
{
"message": "previous",
"type": "InvalidArgumentException",
"code": 0,
"line": 20,
"file": "exception.php",
"trace": [
"#0 [internal function]: ...",
"#1 [internal function]: ...",
"#3 [internal function]: ...",
"..."
]
}
]
}
}
HttpApiProblem
use Phpro\ApiProblem\Http\HttpApiProblem; new HttpApiProblem(404, ['detail' => 'The book could not be found.']);
{
"status": 404,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Not found",
"detail": "The book could not be found."
}
ValidationApiProblem
composer require symfony/validator:^4.1
use Phpro\ApiProblem\Http\ValidationApiProblem; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; new ValidationApiProblem(new ConstraintViolationList([ new ConstraintViolation('Invalid email', '', [], '', 'email', '', null, '8615ecd9-afcb-479a-9c78-8bcfe260cf2a'), ]));
{
"status": 400,
"type": "https:\/\/symfony.com\/errors\/validation",
"title": "Validation Failed",
"detail": "email: Invalid Email",
"violations": [
{
"propertyPath": "email",
"title": "Invalid email",
"type": "urn:uuid:8615ecd9-afcb-479a-9c78-8bcfe260cf2a"
}
]
}
BadRequestProblem
use Phpro\ApiProblem\Http\BadRequestProblem; new BadRequestProblem('Bad request. Bad!.');
{
"status": 400,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Bad Request",
"detail": "Bad request. Bad!"
}
UnauthorizedProblem
use Phpro\ApiProblem\Http\UnauthorizedProblem; new UnauthorizedProblem('You are not authorized to access X.');
{
"status": 401,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Unauthorized",
"detail": "You are not authenticated. Please login."
}
ForbiddenProblem
use Phpro\ApiProblem\Http\ForbiddenProblem; new ForbiddenProblem('Not authorized to access gold.');
{
"status": 403,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Forbidden",
"detail": "Not authorized to access gold."
}
NotFoundProblem
use Phpro\ApiProblem\Http\NotFoundProblem; new NotFoundProblem('The book with ID 20 could not be found.');
{
"status": 404,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Not found",
"detail": "The book with ID 20 could not be found."
}
MethodNotAllowedProblem
use Phpro\ApiProblem\Http\MethodNotAllowedProblem; new MethodNotAllowedProblem('Only POST and GET allowed.');
{
"status": 405,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Method Not Allowed",
"detail": "Only POST and GET allowed."
}
ConflictProblem
use Phpro\ApiProblem\Http\ConflictProblem; new ConflictProblem('Duplicated key for book with ID 20.');
{
"status": 409,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Conflict",
"detail": "Duplicated key for book with ID 20."
}
PreconditionFailedProblem
use Phpro\ApiProblem\Http\PreconditionFailedProblem; new PreconditionFailedProblem('Incorrect entity tag provided.');
{
"status": 412,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Precondition Failed",
"detail": "Incorrect entity tag provided."
}
UnsupportedMediaTypeProblem
use Phpro\ApiProblem\Http\UnsupportedMediaTypeProblem; new UnsupportedMediaTypeProblem('Please provide valid JSON.');
{
"status": 415,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Unsupported Media Type",
"detail": "Please provide valid JSON."
}
IAmATeapotProblem
use Phpro\ApiProblem\Http\IAmATeapotProblem; new IAmATeapotProblem('More tea please.');
{
"status": 418,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "I'm a teapot",
"detail": "More tea please."
}
UnprocessableEntityProblem
use Phpro\ApiProblem\Http\UnprocessableEntityProblem; new UnprocessableEntityProblem('Unable to process the contained instructions.');
{
"status": 422,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Unprocessable Entity",
"detail": "Unable to process the contained instructions."
}
LockedProblem
use Phpro\ApiProblem\Http\LockedProblem; new LockedProblem('This door is locked.');
{
"status": 423,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Locked",
"detail": "This door is locked."
}
PreconditionRequiredProblem
use Phpro\ApiProblem\Http\PreconditionRequiredProblem; new PreconditionRequiredProblem('If-match header is required.');
{
"status": 428,
"type": "http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html",
"title": "Precondition Required",
"detail": "If-match header is required."
}
Creating your own problem
Creating problem sounds scary right!? Since the RFC is very loose, we made the interface as easy as possible:
use Phpro\ApiProblem\ApiProblemInterface; class MyProblem implements ApiProblemInterface { public function toArray(): array { return [ 'type' => 'about:blank', 'status' => '99', 'title' => 'Got 99 problems but a glitch aint one!', ]; } }
A lot of problems will be detected in an HTTP context. Therefore, we also provided a base HttpApiProblem class.
This one will automatically fill in the type and title section based on the HTTP code.
The only thing you'll need to do, is add some additional data to it:
use Phpro\ApiProblem\Http\HttpApiProblem; class MyProblem extends HttpApiProblem { public function __construct(string $details) { parent::__construct(500, ['details' => $details]); } }
If you want to log additional information in a debug context, it is possible to implement an additional DebuggableApiProblemInterface:
use Phpro\ApiProblem\DebuggableApiProblemInterface; class MyProblem implements DebuggableApiProblemInterface { public function toArray(): array { return [ 'type' => 'about:blank', 'status' => '99', 'title' => 'Got 99 problems but a glitch ain\'t one!', ]; } public function toDebuggableArray(): array { return array_merge( $this->toArray(), [ 'situation' => 'If you are having code problems, I feel bad for you son', ] ); } }
About
Submitting bugs and feature requests
Bugs and feature request are tracked on GitHub. Please take a look at our rules before contributing your code.
License
api-problem is licensed under the MIT License.
phpro/api-problem 适用场景与选型建议
phpro/api-problem 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 848.09k 次下载、GitHub Stars 达 67, 最近一次更新时间为 2018 年 08 月 31 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 phpro/api-problem 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 phpro/api-problem 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 848.09k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 68
- 点击次数: 28
- 依赖项目数: 6
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2018-08-31