rnd-cosoft / api-tools-api-problem
Laminas 模块,提供 API-Problem 资产和渲染功能
Requires
- php: ~8.1.0 || ~8.2.0 || ~8.3.0
- ext-json: *
- laminas/laminas-eventmanager: ^2.6.3 || ^3.4.0
- laminas/laminas-http: ^2.15.1
- laminas/laminas-json: ^2.6.1 || ^3.3
- laminas/laminas-mvc: ^2.7.15 || ^3.3.0
- laminas/laminas-view: ^2.14.0
- laminas/laminas-zendframework-bridge: ^1.1
Requires (Dev)
- laminas/laminas-coding-standard: ~2.3.0
- phpspec/prophecy-phpunit: ^2.0.1
- phpunit/phpunit: ^9.5.27
- psalm/plugin-phpunit: ^0.16.1
- vimeo/psalm: ^4.30
Replaces
README
🇷🇺 俄罗斯公民
我们,Laminas 的参与者,来自不同的国家。我们中许多人都有在俄罗斯和乌克兰的朋友、亲戚和同事。我们中的一些人生在俄罗斯,一些人在俄罗斯生活。我们中的一些祖父母在二战中与法西斯作战。在这里,没有人支持法西斯主义。
我们中的一位成员有一位乌克兰亲戚,她和儿子一起从家中逃出。火车因前方道路上的轰炸而延误。我们有朋友躲在防空洞里。我们在空袭后焦虑地等待他们的消息,空袭不分青红皂白地攻击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些,我们是直接目睹的。
您足够信任我们,愿意使用我们的程序,我们请求您再次信任我们。我们需要帮助。走出家门,抗议这场毫无意义的战争。停止流血。说“停止战争!”
🇺🇸 致俄罗斯公民
我们来自世界各地。我们中许多人都有在俄罗斯和乌克兰的朋友、家人和同事。我们中的一些人生在俄罗斯,一些人在俄罗斯生活。我们中的一些祖父母在二战中与纳粹作战。在这里,没有人支持法西斯主义。
我们的一位团队成员有一位乌克兰亲戚,她和儿子一起逃离了家园。火车因前方道路上的轰炸而延误。我们有朋友躲在防空洞里。我们在空袭后焦虑地等待他们的消息,空袭不分青红皂白地攻击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些,这是我们亲身体验到的。
您足够信任我们,愿意使用我们的软件。我们请求您信任我们,说出真相。我们需要您的帮助。走出家门,抗议这场不必要的战争。停止杀戮。说“停止战争!”
介绍
本模块提供 API-Problem 格式的数据结构和渲染。
- HTTP API 的问题细节,用于报告 API 问题。
要求
请参阅 composer.json 文件。
安装
运行以下 composer
命令
$ composer require laminas-api-tools/api-tools-api-problem
或者,手动将以下内容添加到您的 composer.json
文件的 require
部分中
"require": { "laminas-api-tools/api-tools-api-problem": "^1.2" }
然后运行 composer update
以确保模块已安装。
最后,将模块名称添加到项目 config/application.config.php
文件下的 modules
键下
return [ /* ... */ 'modules' => [ /* ... */ 'Laminas\ApiTools\ApiProblem', ], /* ... */ ];
laminas-component-installer
如果您使用 laminas-component-installer,该插件将为您安装 api-tools-api-problem 作为模块。
配置
用户配置
此模块用户配置的最高级配置键是 api-tools-api-problem
。
键:accept_filters
一个数组,包含匹配的 Accept
头部媒体类型,当匹配时,将导致 ApiProblemListener 处理 MvcEvent::EVENT_RENDER_ERROR
事件。
键:render_error_controllers
一个控制器服务名称数组,当与 MVC 的 RouteMatch
中的 controller
参数匹配时,将导致 ApiProblemListener 处理 MvcEvent::EVENT_RENDER_ERROR
事件。
系统配置
以下配置在 config/module.config.php
中提供,以启用模块功能
'service_manager' => [ 'aliases' => [ 'Laminas\ApiTools\ApiProblem\ApiProblemListener' => 'Laminas\ApiTools\ApiProblem\Listener\ApiProblemListener', 'Laminas\ApiTools\ApiProblem\RenderErrorListener' => 'Laminas\ApiTools\ApiProblem\Listener\RenderErrorListener', 'Laminas\ApiTools\ApiProblem\ApiProblemRenderer' => 'Laminas\ApiTools\ApiProblem\View\ApiProblemRenderer', 'Laminas\ApiTools\ApiProblem\ApiProblemStrategy' => 'Laminas\ApiTools\ApiProblem\View\ApiProblemStrategy', ], 'factories' => [ 'Laminas\ApiTools\ApiProblem\Listener\ApiProblemListener' => 'Laminas\ApiTools\ApiProblem\Factory\ApiProblemListenerFactory', 'Laminas\ApiTools\ApiProblem\Listener\RenderErrorListener' => 'Laminas\ApiTools\ApiProblem\Factory\RenderErrorListenerFactory', 'Laminas\ApiTools\ApiProblem\Listener\SendApiProblemResponseListener' => 'Laminas\ApiTools\ApiProblem\Factory\SendApiProblemResponseListenerFactory', 'Laminas\ApiTools\ApiProblem\View\ApiProblemRenderer' => 'Laminas\ApiTools\ApiProblem\Factory\ApiProblemRendererFactory', 'Laminas\ApiTools\ApiProblem\View\ApiProblemStrategy' => 'Laminas\ApiTools\ApiProblem\Factory\ApiProblemStrategyFactory', ], ], 'view_manager' => [ // Enable this in your application configuration in order to get full // exception stack traces in your API-Problem responses. 'display_exceptions' => false, ],
Laminas 事件
监听器
Laminas\ApiTools\ApiProblem\Listener\ApiProblemListener
ApiProblemListener
链接到 MVC 生命周期中的三个事件
MvcEvent::EVENT_DISPATCH
作为 共享 监听器在Laminas\Stdlib\DispatchableInterface
上,优先级为100
。MvcEvent::EVENT_DISPATCH_ERROR
,优先级为100
。MvcEvent::EVENT_RENDER
,优先级为1000
。
如果当前的 Accept
媒体类型与配置的 API-Problem 媒体类型不匹配(默认情况下,这些是 application/json
和 application/*+json
),则此监听器将不采取任何行动。
当此监听器采取行动时,有三个目的
- 在调度之前,将检查
render_error_controllers
配置值,以确定是否应附加Laminas\ApiTools\ApiProblem\Listener\RenderErrorListener
;有关更多信息,请参阅 RenderErrorListener。 - 在调度之后,检测来自控制器的响应类型;如果是
ApiProblem
模型,则继续而不做任何事情。如果在调度期间抛出了异常,则将其转换为带有一些异常信息的 API-Problem 响应。 - 如果发生调度错误,并且
Accept
类型在为 API-Problems 定义的集合中,则尝试将调度异常转换为 API-Problem 响应。
Laminas\ApiTools\ApiProblem\Listener\RenderErrorListener
此监听器在优先级 100
时附加到 MvcEvent::EVENT_RENDER_ERROR
。此监听器由 Laminas\ApiTools\ApiProblem\Listener\ApiProblemListener
有条件地附加到需要 API 问题响应的控制器。优先级为 100
确保此监听器在此事件上在默认的 Laminas 监听器之前运行。在它运行的情况下,它将异常转换为 API-问题响应。
Laminas\ApiTools\ApiProblem\Listener\SendApiProblemResponseListener
此监听器在优先级 -500
时附加到 SendResponseEvent::EVENT_SEND_RESPONSE
。此监听器的主要目的是,在检测到 API-Problem 响应时,发送适当的头信息和问题详情作为内容主体。如果 view_manager
的 display_exceptions
设置已启用,则监听器将确定 API-Problem 是否代表应用程序异常,如果是,则将异常跟踪作为序列化响应的一部分注入。
Laminas 服务
事件服务
Laminas\ApiTools\ApiProblem\Listener\ApiProblemListener
Laminas\ApiTools\ApiProblem\Listener\RenderErrorListener
Laminas\ApiTools\ApiProblem\Listener\SendApiProblemResponseListener
视图服务
Laminas\ApiTools\ApiProblem\View\ApiProblemRenderer
此服务扩展了来自 Laminas MVC 层的 JsonRenderer
服务。其主要责任是在可选地输出堆栈跟踪的能力下装饰 JSON 渲染。
Laminas\ApiTools\ApiProblem\View\ApiProblemStrategy
此服务是一种视图策略,用于检测 Laminas\ApiTools\ApiProblem\View\ApiProblemModel
;当检测到时,它选择 ApiProblemRender,并将带有 application/problem+json
媒体类型的 Content-Type
头部注入到响应中。这与 Laminas 的 JsonStrategy
类似。
模型
Laminas\ApiTools\ApiProblem\ApiProblem
Laminas\ApiTools\ApiProblem\ApiProblem
的一个实例用于建模遇到的类型的问题。通常将 ApiProblem
实例包装在 ApiProblemResponse 中。大多数信息都可以传递到构造函数中
class ApiProblem { public function __construct( $status, $detail, $type = null, $title = null, array $additional = [] ) { /* ... */ } }
例如
new ApiProblem(404, 'Entity not found'); // or new ApiProblem(424, $exceptionInstance);
Laminas\ApiTools\ApiProblem\ApiProblemResponse
可以从任何控制器服务或 Laminas MVC 事件返回一个 Laminas\ApiTools\ApiProblem\ApiProblemResponse
实例,以短路 MVC 生命周期并立即返回响应。当这样做时,响应将被转换为 API-Problem 的正确 JSON 结构,并将 Content-Type
头设置为 application/problem+json
媒体类型。
例如
use Laminas\Mvc\Controller\AbstractActionController; use Laminas\ApiTools\ApiProblem\ApiProblem; use Laminas\ApiTools\ApiProblem\ApiProblemResponse; class MyController extends AbstractActionController { /* ... */ public function fetch($id) { $entity = $this->model->fetch($id); if (! $entity) { return new ApiProblemResponse(new ApiProblem(404, 'Entity not found')); } return $entity; } }