bavix/json-api

此包已废弃,不再维护。没有建议的替代包。

PHP 中的 JSON-API 响应

1.1.0 2021-02-26 14:26 UTC

This package is auto-updated.

Last update: 2023-01-26 18:47:49 UTC


README

Build Status Coverage Status Quality Score Pre Release License

JSON-API 在 PHP 中的响应。

与规范版本 1.0 兼容。

安装

通过 Composer

composer require bavix/json-api

用法

use Tobscure\JsonApi\Document;
use Tobscure\JsonApi\Collection;

// Create a new collection of posts, and specify relationships to be included.
$collection = (new Collection($posts, new PostSerializer))
    ->with(['author', 'comments']);

// Create a new JSON-API document with that collection as the data.
$document = new Document($collection);

// Add metadata and links.
$document->addMeta('total', count($posts));
$document->addLink('self', 'http://example.com/api/posts');

// Output the document as JSON.
echo json_encode($document);

元素

JSON-API 规范将 资源对象 描述为包含单个资源信息的对象,将 集合对象 描述为包含多个资源信息的对象。在此包中

  • Tobscure\JsonApi\Resource 表示一个 资源对象
  • Tobscure\JsonApi\Collection 表示一个 集合对象

资源和集合都被称为 元素。在概念上与 JSON-API 规范描述的相同,资源可以与任何数量的其他元素(资源用于一对一关系,集合用于一对多)有 关系。同样,集合可以包含多个资源。

JSON-API 文档可以包含一个主元素。主元素将被递归解析以与其他元素的关系;这些元素将被添加到文档中作为 包含 的资源。

稀疏字段集

您可以使用 fields 方法指定要包含在元素上的哪些字段(属性和关系)。您必须提供一个按资源类型组织的多维数组

$collection->fields(['posts' => ['title', 'date']]);

序列化器

序列化器负责为某种资源类型构建属性和关系。序列化器必须实现 Tobscure\JsonApi\SerializerInterface。提供了一个具有一些基本功能的 AbstractSerializer。至少,序列化器必须指定其 类型 并提供一个方法来转换 属性

use Tobscure\JsonApi\AbstractSerializer;

class PostSerializer extends AbstractSerializer
{
    protected $type = 'posts';

    public function getAttributes($post, array $fields = null)
    {
        return [
            'title' => $post->title,
            'body'  => $post->body,
            'date'  => $post->date
        ];
    }
}

默认情况下,资源对象的 id 属性将被设置为模型上的 id 属性。序列化器可以提供一个方法来覆盖此设置

public function getId($post)
{
    return $post->someOtherKey;
}

关系

AbstractSerializer 允许您为资源中存在的每个关系定义一个公共方法。关系方法应返回一个 Tobscure\JsonApi\Relationship 实例。

public function comments($post)
{
    $element = new Collection($post->comments, new CommentSerializer);

    return new Relationship($element);
}

默认情况下,AbstractSerializer 将将关系名称从 kebab-casesnake_case 转换为 camelCase 方法名称,并在序列化器上调用该名称。如果您希望自定义此行为,您可能需要覆盖 getRelationship 方法

public function getRelationship($model, $name)
{
    // resolve Relationship called $name for $model
}

元数据 & 链接

DocumentResourceRelationship 类允许您添加元信息

$document = new Document;
$document->addMeta('key', 'value');
$document->setMeta(['key' => 'value']);

它们还允许以类似的方式添加链接

$resource = new Resource($data, $serializer);
$resource->addLink('self', 'url');
$resource->setLinks(['key' => 'value']);

您还可以轻松地添加分页链接

$document->addPaginationLinks(
    'url', // The base URL for the links
    [],    // The query params provided in the request
    40,    // The current offset
    20,    // The current limit
    100    // The total number of results
);

序列化器也可以提供链接和/或元数据

use Tobscure\JsonApi\AbstractSerializer;

class PostSerializer extends AbstractSerializer
{
    // ...
    
    public function getLinks($post) {
        return ['self' => '/posts/' . $post->id];
    }

    public function getMeta($post) {
        return ['some' => 'metadata for ' . $post->id];
    }
}

注意:资源的链接和元数据将覆盖具有相同键的序列化器的那些!

参数

Tobscure\JsonApi\Parameters 类允许您轻松地根据规范解析和验证查询参数。

use Tobscure\JsonApi\Parameters;

$parameters = new Parameters($_GET);

getInclude

获取请求包含的关联关系。提供一个可用的关系路径数组;如果存在其他任何内容,将抛出 InvalidParameterException 异常。

// GET /api?include=author,comments
$include = $parameters->getInclude(['author', 'comments', 'comments.author']); // ['author', 'comments']

getFields

获取请求包含的字段,键为资源类型。

// GET /api?fields[articles]=title,body
$fields = $parameters->getFields(); // ['articles' => ['title', 'body']]

getSort

获取请求的排序标准。提供一个可以排序的可用字段数组;如果存在其他任何内容,将抛出 InvalidParameterException 异常。

// GET /api?sort=-created,title
$sort = $parameters->getSort(['title', 'created']); // ['created' => 'desc', 'title' => 'asc']

getLimit 和 getOffset

使用基于页面或偏移的策略获取偏移量数字和要显示的资源数量。 getLimit 接受一个可选的最大值。如果计算出的偏移量小于零,将抛出 InvalidParameterException 异常。

// GET /api?page[number]=5&page[size]=20
$limit = $parameters->getLimit(100); // 20
$offset = $parameters->getOffset($limit); // 80

// GET /api?page[offset]=20&page[limit]=200
$limit = $parameters->getLimit(100); // 100
$offset = $parameters->getOffset(); // 20

错误处理

您可以使用 Tobscure\JsonApi\ErrorHandler 类将捕获的异常转换为 JSON-API 错误文档。您必须注册适当的 Tobscure\JsonApi\Exception\Handler\ExceptionHandlerInterface 实例。

try {
    // API handling code
} catch (Exception $e) {
    $errors = new ErrorHandler;

    $errors->registerHandler(new InvalidParameterExceptionHandler);
    $errors->registerHandler(new FallbackExceptionHandler);

    $response = $errors->handle($e);

    $document = new Document;
    $document->setErrors($response->getErrors());

    return new JsonResponse($document, $response->getStatus());
}

贡献

如果您遇到问题或有很多好主意,请随意发送拉取请求或创建问题。任何输入都受欢迎!

运行测试

$ phpunit

许可

此代码根据 MIT 许可证 发布。这意味着只要保留版权声明和随附的许可文件,您几乎可以做任何事情。