noc-med/zf-api-problem

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

1.0.1 2014-06-03 22:10 UTC

README

Build Status

介绍

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

要求

请参阅 composer.json 文件。

安装

运行以下 composer 命令

$ composer require "zfcampus/zf-api-problem:~1.0-dev"

或者,手动将以下内容添加到您的 composer.json 文件的 require 部分

"require": {
    "zfcampus/zf-api-problem": "~1.0-dev"
}

然后运行 composer update 以确保模块已安装。

最后,将模块名称添加到项目 config/application.config.php 下的 modules 键中

return array(
    /* ... */
    'modules' => array(
        /* ... */
        'ZF\ApiProblem',
    ),
    /* ... */
);

配置

用户配置

本模块的用户配置顶级配置键是 zf-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' => array(
    'aliases'   => array(
        'ZF\ApiProblem\ApiProblemListener'  => 'ZF\ApiProblem\Listener\ApiProblemListener',
        'ZF\ApiProblem\RenderErrorListener' => 'ZF\ApiProblem\Listener\RenderErrorListener',
        'ZF\ApiProblem\ApiProblemRenderer'  => 'ZF\ApiProblem\View\ApiProblemRenderer',
        'ZF\ApiProblem\ApiProblemStrategy'  => 'ZF\ApiProblem\View\ApiProblemStrategy',
    ),
    'factories' => array(
        'ZF\ApiProblem\Listener\ApiProblemListener'             => 'ZF\ApiProblem\Factory\ApiProblemListenerFactory',
        'ZF\ApiProblem\Listener\RenderErrorListener'            => 'ZF\ApiProblem\Factory\RenderErrorListenerFactory',
        'ZF\ApiProblem\Listener\SendApiProblemResponseListener' => 'ZF\ApiProblem\Factory\SendApiProblemResponseListenerFactory',
        'ZF\ApiProblem\View\ApiProblemRenderer'                 => 'ZF\ApiProblem\Factory\ApiProblemRendererFactory',
        'ZF\ApiProblem\View\ApiProblemStrategy'                 => 'ZF\ApiProblem\Factory\ApiProblemStrategyFactory',
    ),
),
'view_manager' => array(
    // Enable this in your application configuration in order to get full
    // exception stack traces in your API-Problem responses.
    'display_exceptions' => false,
),

ZF2 事件

监听器

ZF\ApiProblem\Listener\ApiProblemListener

ApiProblemListener 附着到 MVC 生命周期中的三个事件

  • MvcEvent::EVENT_DISPATCH,作为具有 100 优先级的 共享 监听器,在 Zend\Stdlib\DispatchableInterface 上。
  • 具有 100 优先级的 MvcEvent::EVENT_DISPATCH_ERROR
  • 具有 1000 优先级的 MvcEvent::EVENT_RENDER

如果当前的 Accept 媒体类型不匹配配置的 API-Problem 媒体类型(默认情况下,这些是 application/jsonapplication/*+json),则此监听器将返回而不采取任何操作。

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

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

ZF\ApiProblem\Listener\RenderErrorListener

该监听器已附加到 MvcEvent::EVENT_RENDER_ERROR 事件,优先级为 100。该监听器由 ZF\ApiProblem\Listener\ApiProblemListener 条件性地附加到需要 API 问题响应的控制器。优先级设置为 100 确保此监听器在默认 ZF2 监听器之前运行。当它运行时,它将异常转换为 API 问题响应。

ZF\ApiProblem\Listener\SendApiProblemResponseListener

该监听器已附加到 SendResponseEvent::EVENT_SEND_RESPONSE 事件,优先级为 -500。此监听器的主要目的是在检测到 API 问题响应时,发送适当的头信息和问题详情作为内容主体。如果 view_managerdisplay_exceptions 设置被启用,监听器将确定 API 问题是否代表应用程序异常,如果是,则将异常跟踪作为序列化响应的一部分注入。

ZF2 服务

事件服务

  • ZF\ApiProblem\Listener\ApiProblemListener
  • ZF\ApiProblem\Listener\RenderErrorListener
  • ZF\ApiProblem\Listener\SendApiProblemResponseListener

视图服务

ZF\ApiProblem\View\ApiProblemRenderer

此服务扩展了 ZF2 MVC 层的 JsonRenderer 服务。其主要责任是装饰 JSON 渲染,并具有可选地输出堆栈跟踪的能力。

ZF\ApiProblem\View\ApiProblemStrategy

此服务是一种视图策略,用于检测 ZF\ApiProblem\View\ApiProblemModel;当检测到时,它选择 ApiProblemRender,并将响应注入带有 Content-Type 头的响应中,该头包含 application/problem+json 媒体类型。这与 Zend Framework 2 的 JsonStrategy 类似。

模型

ZF\ApiProblem\ApiProblem

ZF\ApiProblem\ApiProblem 的实例用于建模遇到的问题类型。通常,ApiProblem 的实例被包装在一个 ApiProblemResponse 中。大多数信息都可以传递给构造函数。

class ApiProblem {
    public function __construct(
        $status,
        $detail,
        $type = null,
        $title = null,
        array $additional = array()
    ) {
        /* ... */
    }
}

例如

new ApiProblem(404, 'Entity not found');

// or

new ApiProblem(424, $exceptionInstance);

ZF\ApiProblem\ApiProblemResponse

ZF\ApiProblem\ApiProblemResponse 的实例可以从任何控制器服务或 ZF2 MVC 事件中返回,以短路 MVC 生命周期并立即返回响应。当这样做时,响应将转换为 API 问题的正确 JSON 结构,并将 Content-Type 头设置为 application/problem+json 媒体类型。

例如

use Zend\Mvc\Controller\AbstractActionController;
use ZF\ApiProblem\ApiProblem;
use ZF\ApiProblem\ApiProblemResponse;

class MyController extends AbstractActionController
{
    /* ... */
    public function fetch($id)
    {
        $entity = $this->model->fetch($id);
        if (! $entity) {
            return new ApiProblemResponse(ApiProblem(404, 'Entity not found'));
        }
        return $entity;
    }
}