sitegeist/schemeonyou

Neos.Flow 的 JSON Schema 集成


README

使用标量类型、数据传输对象(DTO)和 DTO 集合构建 API。

TLDR

差异

  • 控制器扩展 Sitegeist\SchemeOnYou\Application\OpenApiController
  • 控制器动作必须接受和返回受支持的类型。
  • 受支持的类型包括标量值、DTO 和 DTO 集合,以及 PHP 日期对象的特例。

优势

  • 更简单的控制器逻辑!
  • 控制器可以完全分析!
  • 可以通过单元测试测试控制器!
  • OpenApi 文档会动态生成,不会偏离事实。
  • 可以通过属性定义返回类型和其他细节。

注意事项

  • 进出的一切都必须使用命名和受支持的类型。
  • 不得将普通数组用作类型。
  • 除了方法返回值之外,联合类型目前还不支持。

作者和赞助商

此包的开发和公共发布得到了我们雇主 http://www.sitegeist.de 的慷慨赞助。

构建 API

配置 OpenAPI 文档

该包允许指定多个 OpenAPI 文档。每个扩展 \Sitegeist\SchemeOnYou\Application\OpenApiController 并匹配配置的 classNames 模式的类都将包含到 API 文档中。

Sitegeist:
  SchemeOnYou:
    documents:
      example:
        name: "Example OpenApi document"
        classNames:
          - 'Vendor\Example\Controller\*'

配置的 OpenApi 文档规范可以通过 cli ./flow openapidocument:render {name} 或通过 URL 路径 /openapi/document/{name} 渲染。

创建 OpenApi 控制器

包含在生成的文档中的 OpenApi 端点都是控制器中扩展了 Sitegeist\SchemeOnYou\Application\OpenApiController*Action 方法,并且可以通过路由访问。控制器必须指定每个参数的类型以及返回类型。

!!! 目前仅在动作方法的返回值中允许联合类型。!!!

<?php
declare(strict_types=1);
namespace Vendor\Example\Controller;

use Neos\Flow\Annotations as Flow;
use Sitegeist\SchemeOnYou\Application\OpenApiController;
use Vendor\Example\Dto;

class ExampleOpenApiController extends OpenApiController
{
    public function indexAction(Query $query, string $language = 'de'): Dto\AddressCollection|Dto\NotFoundResponse {
        ... 
    }
}

PHP 属性

以下 PHP 属性允许指定参数和模式处理的详细信息。

  • 控制器动作参数
    • \Sitegeist\SchemeOnYou\Domain\Metadata\RequestBody 可以将单个方法参数标记为请求体
    • \Sitegeist\SchemeOnYou\Domain\Metadata\Parameter 所有其他参数可以标记为通过 querypathheadercookie 传输。如果没有属性,则将该参数处理为 query 参数。
  • DTO 类
    • \Sitegeist\SchemeOnYou\Domain\Metadata\Response 响应属性允许为 DTO 设置除 200 之外的状态码。
    • \Sitegeist\SchemeOnYou\Domain\Metadata\Schema schema 属性指定 DTO 的名称和描述,如果要从 PHP 名称中派生,则不这样做。

支持的类型

该包支持以下属性类型。您会注意到这里没有数组,但有 DTO 和集合,这允许更精细地控制属性转换。

标量值

类型为 stringintfloatbool 的值可以直接由 OpenApi 允许,无需转换。

!!! 不允许将 null 作为单一类型。但是,可空值是被允许的 !!!

PHP 日期对象

类型为 \DateTime\DateTimeImmutable\DateInterval 的对象可以作为例外。值将以预定义的格式序列化为字符串。

后端枚举

支持后端枚举,通过将其转换为底层值或从底层值转换而来。

数据传输对象 (DTOs)

受支持的数据传输对象必须遵循以下规则

  • 类是 readonly
  • 类有一个公共构造函数
  • 构造函数中的所有参数都是 publicpromoted 且为受支持类型
  • 属性的数量等于构造函数参数的数量
#[Flow\Proxy(false)]
final readonly class Address
{
    public function __construct(
        public string $streetAddress,
        public ?string $addressRegion,
        public ?string $addressCountry = 'DE',
        public ?string $postOfficeBoxNumber = null
    ) {
    }
}

如果 DTO 有一个名为 value 的单个属性,则将其序列化为该单个值。在其他所有情况下,DTO 将序列化为一个包含所有构造函数属性的数组。

#[Flow\Proxy(false)]
final readonly class Identifier
{
    public function __construct(
        public string $value,
    ) {
    }
}

DTO 对象集合

受支持的集合对象必须遵循以下规则

  • 类是 readonly
  • 类有一个公共构造函数
  • 构造函数有一个单个的可变参数,类型为受支持类型
  • 类有一个单一的 publicreadonly 属性
#[Flow\Proxy(false)]
final readonly class AddressCollection
{
    /**
     * @var Address[]
     */
    public array $items;

    public function __construct(Address ...$items)
    {
        $this->items = array_values($items);
    }
}

!!! 有很小的可能性,传递给构造函数的参数不会被存储在类的属性中。我们必须接受这一点,直到可变参数可以被提升。 !!!

安装

Sitegeist.SchemeOnYou 通过 packagist 提供。运行 composer require sitegeist/schemeonyou 以添加此包。

我们使用语义版本控制,所以每次重大变更都会增加主版本号。

贡献

我们乐意接受贡献。请向我们发送 pull requests。