juliangut/json-api

PSR7 识别的 json-api 集成

dev-master 2024-03-07 17:53 UTC

This package is auto-updated.

Last update: 2024-09-15 17:26:06 UTC


README

PHP version Latest Version License

Total Downloads Monthly Downloads

json-api

简单 JSON:API 集成。

安装

Composer

composer require juliangut/json-api

symfony/yaml 解析 yaml 文件

composer require symfony/yaml

用法

需要 composer 自动加载文件

require './vendor/autoload.php';
use Jgut\JsonApi\Manager;
use Jgut\JsonApi\Configuration;
use Neomerx\JsonApi\Schema\Error;

$configuration = new Configuration([
    'sources' => ['/path/to/resource/files'],
]);

$jsonApiManager = new Manager($configuration);

// Get encoded errors
$jsonApiManager->encodeErrors(new Error());

// Get encoded resources
$jsonApiManager->encodeResources(new MyClass(), new ServerRequestInstance());

配置

  • sources 必须是一个数组,包含创建 MappingDriver 对象的配置数组
    • type 是 \Jgut\JsonApi\Mapping\Driver\DriverFactory 常量之一:DRIVER_ATTRIBUTEDRIVER_PHPDRIVER_JSONDRIVER_XMLDRIVER_YAMLDRIVER_ANNOTATION(如果没有驱动程序,默认为 DRIVER_ATTRIBUTE
    • path 一个字符串路径或路径数组,指向映射文件的位置(文件或目录)(如果没有驱动程序,则为必需)
    • driver 已经创建的 \Jgut\JsonApi\Mapping\Driver\DriverInterface 对象(如果没有类型和路径,则为必需)
  • attributeName 将包含资源编码查询参数的 PSR-7 请求属性名称,默认为 'JSON_API_query_parameters'
  • schema 实现了 \Jgut\JsonApi\Schema\MetadataSchemaInterface(默认为 \Jgut\JsonApi\Schema\MetadataSchema)的类名
  • prefix 生成的 URL 的前缀
  • metadataResolver 一个 \Jgut\Mapping\Metadata\MetadataResolver 实例。在生产环境中,强烈建议为元数据解析器提供 PSR-16 缓存
  • encodingOptions 全局编码选项,一个 \Jgut\JsonApi\Encoding\OptionsInterface 实例
  • jsonApiVersion 默认无
  • jsonApiMeta 可选的全局元数据

中间件

使用 PSR-15 中间件 Jgut\JsonApi\Middleware\JsonApiMiddleware 来验证请求是否为有效的 JSON:API 规范请求

use Jgut\JsonApi\Manager;
use Jgut\JsonApi\Middleware\JsonApiMiddleware;
use Psr\Http\Message\ResponseFactoryInterface;

/** @var ResponseFactoryInterface $responseFactory */
/** @var Manager $jsonApiManager */

$middleware = new JsonApiMiddleware($responseFactory, $jsonApiManager);

// Add the middleware to any PSR-15 compatible library/framework, such as Slim, Mezzio, etc 

控制台命令

use Symfony\Component\Console\Application;
use Jgut\Slim\PHPDI\Command\ListCommand;

/** @var \Slim\App $app */
$container = $app->getContainer();

$cli = new Application('Slim CLI');
$cli->add(new ListCommand($container));

$app->run();

列出容器定义

列出支持搜索的容器定义

资源映射

资源可以通过两种基本方式定义:在定义文件的不同类型中写下它们,或在类的属性上直接定义

属性

ResourceObject(类级别)

标识每个 JSON:API 资源。它在每个资源类中都是强制性的

接受一个可选的 "name" 来覆盖默认值(类名,首字母小写)

use Jgut\JsonApi\Mapping\Attribute\ResourceObject;
use Jgut\JsonApi\Mapping\Attribute\ResourcePrefix;
use Jgut\JsonApi\Mapping\Attribute\ResourceSchema;

#[ResourceObject(
    name: 'company',
    prefix: 'resourcePrefix',
    schema: 'customSchemaClass',
    meta: ['meta1' => 'value'],
)]
class Company
{
}
  • name 可选,资源名称,默认为小写首字母的类名
  • prefix 可选,包含链接时的资源 URL 前缀
  • schema 可选,实现 \Jgut\JsonApi\Schema\MetadataSchemaInterface 的类名。可以覆盖默认值

Identifier(属性级别)

资源标识符

use Jgut\JsonApi\Mapping\Attribute\Getter;
use Jgut\JsonApi\Mapping\Attribute\Identifier;
use Jgut\JsonApi\Mapping\Attribute\ResourceObject;
use Jgut\JsonApi\Mapping\Attribute\Setter;

#[ResourceObject]
class Owner
{
    #[Identifier(
        name: 'identifier',
        getter: 'getIdentifier',
        setter: 'setIdentifier',
        meta: ['meta1' => 'value'],
    )]
    protected string $id;
}
  • name 可选,标识符名称,默认为小写首字母的属性名
  • getter 可选,在类中提供对属性访问的方法。默认情况下,布尔类型的前缀为 "is",其余类型的前缀为 "get"
  • setter 可选,在类中设置属性值的方法,前缀为 "set"
  • meta 可选,标识符元数据的可选数组/值数组

Attribute(属性级别)

资源属性

use Jgut\JsonApi\Mapping\Attribute\Attribute;
use Jgut\JsonApi\Mapping\Attribute\Getter;
use Jgut\JsonApi\Mapping\Attribute\ResourceObject;
use Jgut\JsonApi\Mapping\Attribute\Setter;

#[ResourceObject]
class Company
{
    #[Attribute(
        name: 'title',
        getter: 'getTitle',
        setter: 'setTitle',
        groups: ['view'],
    )]
    protected string $title;
}
  • name 可选,属性名称,默认为小写首字母的属性名
  • getter 可选,在类中提供对属性访问的方法。默认情况下,布尔类型的前缀为 "is",其余类型的前缀为 "get"
  • setter 可选,在类中设置属性值的方法,前缀为 "set"
  • groups 可选,属性所属的组数组

Relationship(属性级别)

资源关系

use Jgut\JsonApi\Mapping\Attribute\Relationship;
use Jgut\JsonApi\Mapping\Attribute\ResourceObject;

#[ResourceObject]
class Company
{
    #[Relationship(
        name: 'owner',
        getter: 'getOwner',
        setter: 'setOwner',
        groups: ['view'],
    )]
    protected Owner $companyOwner;
}
  • name,可选,关系名称,默认为小写字母开头的属性名称
  • getter 可选,在类中提供对属性访问的方法。默认情况下,布尔类型的前缀为 "is",其余类型的前缀为 "get"
  • setter 可选,在类中设置属性值的方法,前缀为 "set"
  • groups,可选,关系所属的组数组

链接

use Jgut\JsonApi\Mapping\Attribute\Link;
use Jgut\JsonApi\Mapping\Attribute\LinkRelated;
use Jgut\JsonApi\Mapping\Attribute\LinkSelf;
use Jgut\JsonApi\Mapping\Attribute\ResourceObject;
use Jgut\JsonApi\Mapping\Attribute\Relationship;

#[ResourceObject]
#[LinkSelf(false)]
#[LinkRelated]
#[Link(
    href: 'http://...',
    title: 'example',
    meta: ['meta1' => 'value'],
)]
class Company
{
    #[Relationship]
    #[LinkSelf]
    #[LinkRelated(false)]
    #[Link(
        href: 'http://...',
        title: 'example',
        meta: ['meta1' => 'value'],
    )]
    protected Owner $companyOwner;
}
LinkSelf(类级别)

确定是否将自链接包含在响应中

LinkRelated(类级别)

确定当资源作为关系包含时,是否将自链接包含在响应中

Link(类和属性级别)

根据需要为资源或字段添加尽可能多的自定义链接

  • href,必需,链接的href
  • title,可选,链接标题
  • meta,可选,可选链接元数据的列表(见以下元数据部分)

元数据

use Jgut\JsonApi\Mapping\Attribute\Attribute;
use Jgut\JsonApi\Mapping\Attribute\Meta;
use Jgut\JsonApi\Mapping\Attribute\Relationship;
use Jgut\JsonApi\Mapping\Attribute\ResourceObject;

#[ResourceObject]
#[Meta(key: 'meta1', value: 'value')]
class Company
{
    #[Identifier]
    #[Meta(key: 'meta2', value: 'value')]
    protected string $id;
    
    #[Relationship]
    #[Meta(key: 'meta3', value: 'value')]
    #[Meta(key: 'meta4', value: 'value')]
    protected Owner $owner;
}

有两种类型的元数据

Meta Attribute(类和属性级别)

将一个或多个元数据分配给资源、标识符或关系

  • key,必需,元数据键
  • value,必需,元数据值
其他元数据

链接属性接受元数据作为键/值数组

定义文件

PHP
return [
    [
        'class' => 'CompanyClass',
        'name' => 'company',
        'prefix' => 'company',
        'schema' => 'MetadataCompanySchemaClass',
        'linkSelf' => true,
        'linkRelated' => false,
        'meta' => [
            'meta1' => 'value',
        ],
        'identifier' => [
            'property' => 'uuid',
            'name' => 'id',
            'getter' => 'getUuid',
            'setter' => 'setUuid',
            'meta' => [
                'meta2' => 'value',
            ]
        ],
        'attributes' => [
            [
                'property' => 'email',
                'name' => 'email',
                'getter' => 'getEmail',
                'setter' => 'setEmail',
            ],
        ],
        'relationships' => [
            [
                'class' => 'OwnerClass',
                'property' => 'owner',
                'name' => 'owner',
                'linkSelf' => true,
                'linkRelated' => true,
                'links' => [
                    'example' => [
                        'href' => 'http://example.com',
                        'meta' => [
                            'meta3' => 'value',
                        ],
                    ],
                ],
                'meta' => [
                    'meta4' => 'value',
                ],
            ],
        ],
    ],
];
JSON
[
  {
    "class": "CompanyClass",
    "name": "company",
    "prefix": "company",
    "schema": "MetadataCompanySchemaClass",
    "linkSelf": true,
    "linkRelated": false,
    "meta": {
      "meta1": "value"
    },
    "identifier": {
      "property": "uuid",
      "name": "id",
      "getter": "getUuid",
      "setter": "setUuid",
      "meta": {
        "meta2": "value"
      }
    },
    "attributes": [
      {
        "property": "email",
        "name": "email",
        "getter": "getEmail",
        "setter": "setEmail"
      }
    ],
    "relationships": [
      {
        "class": "OwnerClass",
        "property": "owner",
        "name": "owner",
        "linkSelf": true,
        "linkRelated": true,
        "links": {
          "example": {
            "href": "http://example.com",
            "meta": {
              "meta3": "value"
            }
          }
        },
        "meta": {
          "meta4": "value"
        }
      }
    ]
  }
]
XML
<?xml version="1.0" encoding="utf-8"?>
<root>
  <resource
    class="CompanyClass"
    name="company"
    prefix="company"
    schema="MetadataCompanySchemaClass"
    linkSelf="true"
    linkRelated="false"
  >
    <meta>
      <meta1>value</meta1>
    </meta>
    <identifier property="uuid" name="id" getter="getUuid" setter="setUuid">
      <meta>
        <meta2>value</meta2>
      </meta>
    </identifier>
    <attributes>
      <attribute1 property="email" name="email" getter="getEmail" setter="setEmail"/>
    </attributes>
    <relationships>
      <relationship1 class="OwnerClass" property="owner" name="owner" linkSelf="true" linkRelated="true">
        <links>
          <example href="http://example.com">
            <meta>
              <meta3>value</meta3>
            </meta>
          </example>
        </links>
        <meta>
          <meta4>value</meta4>
        </meta>
      </relationship1>
    </relationships>
  </resource>
</root>
YAML
- class: "CompanyClass"
  name: "company"
  prefix: "company"
  schema: "MetadataCompanySchemaClass"
  linkSelf: true
  linkRelated: false
  meta:
    meta1: "value"
  identifier:
    property": "uuid"
    name: "id"
    getter: "getUuid"
    setter: "setUuid"
    meta:
      meta2: "value"
  attributes:
    - property: "email"
      name: "email"
      getter: "getEmail"
      setter: "setEmail"
  relationships:
    - class: "OwnerClass"
      property: "owner"
      name: "owner"
      linkSelf: true
      linkRelated: true
      links:
        example:
          href: "http://example.com"
          meta:
            meta3: "value"
      meta:
        meta4: "value"

注释

注释已弃用,最终将被删除。尽可能使用属性映射.

您需要引入Doctrine的注释包

composer require doctrine/annotations

ResourceObject(类级别)

标识每个资源。每个资源类都必须存在

use Jgut\JsonApi\Mapping\Annotation as JJM;

/**
 * @JJM\ResourceObject(
 *     name="company",
 *     schema="CustomSchemaClass",
 *     prefix="resourcePrefix",
 *     linkSelf=true,
 *     linkRelated=false,
 *     links={"link1": "http://...", "link2": "http://..."},
 *     meta={"meta1" => "value", "meta2" => "value"}
 * )
 */
class Company
{
}
  • name 可选,资源名称,默认为小写首字母的类名
  • prefix 可选,包含链接时的资源 URL 前缀
  • schema 可选,实现 \Jgut\JsonApi\Schema\MetadataSchemaInterface 的类名。可以覆盖默认值
  • linkSelf,可选 bool,显示自链接,默认为null
  • linkRelated,可选 bool,包含时显示自链接,默认为null
  • links,可选,资源链接的可选键/值数组列表
  • meta,可选,资源元数据的可选数组/值数组列表

Identifier(属性级别)

资源标识符

use Jgut\JsonApi\Mapping\Annotation as JJM;

/**
 * @JJM\ResourceObject
 */
class Owner
{
    /**
     * @JJM\Identifier(
     *     name="id",
     *     getter="getId",
     *     setter="setId",
     *     meta={"meta1" => "value", "meta2" => "value"}
     * )
     */
    protected $id;
}
  • name 可选,标识符名称,默认为小写首字母的属性名
  • getter 可选,在类中提供对属性访问的方法。默认情况下,布尔类型的前缀为 "is",其余类型的前缀为 "get"
  • setter 可选,在类中设置属性值的方法,前缀为 "set"
  • meta 可选,标识符元数据的可选数组/值数组

Attribute(属性级别)

定义资源上可访问的每个属性

use Jgut\JsonApi\Mapping\Annotation as JJM;

/**
 * @JJM\ResourceObject
 */
class Company
{
    /**
     * @JJM\Attribute(
     *     name="email",
     *     getter="getEmail",
     *     setter="setEmail",
     *     groups={"view"}
     * )
     */
    protected string $email;
}
  • name 可选,属性名称,默认为小写首字母的属性名
  • getter 可选,在类中提供对属性访问的方法。默认情况下,布尔类型的前缀为 "is",其余类型的前缀为 "get"
  • setter 可选,在类中设置属性值的方法,前缀为 "set"
  • groups 可选,属性所属的组数组

Relationship(属性级别)

标识此资源关系

use Jgut\JsonApi\Mapping\Annotation as JJM;

/**
 * @JJM\ResourceObject
 */
class Company
{
    /**
     * @JJM\Relationship(
     *     name="company",
     *     getter="getCompany",
     *     setter="setCompany",
     *     groups=["view"]
     *     linkSelf=true,
     *     linkRelated=false,
     *     links={"link1": "http://...", "link2": "http://..."],
     *     meta={"meta1" => ·"value", "meta2" => "value"}
     * )
     */
    protected Owner $company;
}
  • name,可选,关系名称,默认为小写字母开头的属性名称
  • getter 可选,在类中提供对属性访问的方法。默认情况下,布尔类型的前缀为 "is",其余类型的前缀为 "get"
  • setter 可选,在类中设置属性值的方法,前缀为 "set"
  • groups,可选,关系所属的组数组
  • linkSelf,可选 bool,显示自链接,默认为null
  • linkRelated,可选 bool,包含时显示自链接,默认为null
  • links,可选,资源链接的可选键/值数组列表
  • meta,可选,关系元数据的可选数组/值数组列表

贡献

发现了一个错误或有一个功能请求? 请打开一个新问题。在提交之前查看现有的问题。

查看CONTRIBUTING.md文件

许可证

有关许可证条款的副本,请参阅包含在源代码中的LICENSE文件。