laminas-api-tools/api-tools-api-problem

Laminas 模块提供 API-Problem 资产和渲染

1.6.0 2023-01-09 21:28 UTC

README

Build Status

🇷🇺 俄罗斯公民

我们是 Laminas 的成员,来自世界各地。我们中许多人有俄罗斯和乌克兰的朋友、家人和同事。有些人出生在俄罗斯。有些人目前住在俄罗斯。有些人有祖父母在二战中与法西斯作战。在这里,没有人支持法西斯主义。

我们中的一位成员有一位乌克兰亲戚和她儿子一起逃离了家园。由于前方道路上的轰炸,火车延误了。我们有一些朋友在防空洞里躲避。我们在空袭后焦急地跟踪他们,空袭无差别地攻击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些消息。这是我们亲身体验的。

您足够信任我们使用我们的程序,我们请求您再次信任我们。我们需要您的帮助。走出家门,抗议这场毫无意义的战争。停止杀戮。说“停止战争!”

🇺🇸 俄罗斯公民

我们来自世界各地。我们中许多人有俄罗斯和乌克兰的朋友、家人和同事。有些人出生在俄罗斯。有些人目前住在俄罗斯。有些人有祖父母在二战中与纳粹作战。在这里,没有人支持法西斯主义。

我们有一位团队成员有一位乌克兰亲戚和她儿子一起逃离了家园。由于前方道路上的轰炸,火车延误了。我们有一些朋友在防空洞里躲避。我们在空袭后焦急地跟踪他们,空袭无差别地攻击医院、学校、幼儿园和住宅。我们不是从任何媒体上得知这些消息。这是我们亲身体验的。

您足够信任我们使用我们的软件。我们要求您在这件事上信任我们说真话。我们需要您的帮助。走出家门,抗议这场不必要的战争。停止杀戮。说“停止战争!”

简介

本模块提供 API-Problem 格式的数据结构和渲染。

要求

请参阅 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/jsonapplication/*+json),则此监听器将返回而不采取任何操作。

当此监听器采取行动时,有三个目的

  • 在派发之前,将查询 render_error_controllers 配置值以确定是否应该附加 Laminas\ApiTools\ApiProblem\Listener\RenderErrorListener;有关更多信息,请参阅 RenderErrorListener
  • 在派发之后,检测来自控制器的响应类型;如果它已经是一个 ApiProblem 模型,则继续不做任何事情。如果在派发期间抛出异常,则将响应转换为包含异常信息的 API-Problem 响应。
  • 如果发生派发错误,并且 Accept 类型在为 API-Problems 定义的集合中,则尝试将派发异常转换为 API-Problem 响应。

Laminas\ApiTools\ApiProblem\Listener\RenderErrorListener

此监听器在 MvcEvent::EVENT_RENDER_ERROR 事件中以 100 的优先级附加。此监听器通过 Laminas\ApiTools\ApiProblem\Listener\ApiProblemListener 条件性地附加到需要 API 问题响应的控制器。由于优先级为 100,这确保了在此事件上运行此监听器之前先运行默认的 Laminas 监听器。在它确实运行的情况下,它将异常转换为 API 问题响应。

Laminas\ApiTools\ApiProblem\Listener\SendApiProblemResponseListener

此监听器在 SendResponseEvent::EVENT_SEND_RESPONSE 事件中以 -500 的优先级附加。此监听器的主要目的是,在检测到 API-Problem 响应时,发送适当的头信息和问题详细信息作为内容主体。如果 view_managerdisplay_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\ApiTools\ApiProblem\ApiProblemResponse 的实例可以从任何控制器服务或 Laminas MVC 事件返回,以跳过 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;
    }
}