sycho/json-api

PHP中的JSON-API响应

v0.5.2 2023-04-16 10:46 UTC

This package is auto-updated.

Last update: 2024-09-16 13:58:29 UTC


README

Build Status Coverage Status Quality Score Pre Release License

在PHP中实现JSON-API响应。

兼容规范版本1.0。

安装

通过Composer

composer require tobscure/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

获取使用基于页面或偏移量的策略显示的资源偏移数和数量。如果计算的偏移量小于零,将抛出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 许可证 发布。这意味着您可以几乎用它做任何事情,只要保留版权声明和随附的许可证文件即可。