spiral/json-schema-generator

提供从数据传输对象(DTO)类生成JSON模式的能力

v1.1.0 2023-12-06 12:12 UTC

This package is auto-updated.

Last update: 2024-09-06 14:11:08 UTC


README

PHP Version Require Latest Stable Version phpunit psalm Total Downloads psalm-level

JSON Schema Generator是一个PHP包,简化了从数据传输对象(DTO)类生成JSON模式的过程。它支持PHP枚举以及用于数组的泛型类型注解,并提供属性来指定标题、描述和默认值。

主要用例 - 为LLMs提供结构化输出定义。

要求

请确保您的服务器已配置以下PHP版本和扩展

  • PHP >=8.1

安装

您可以通过Composer安装此包

composer require spiral/json-schema-generator

用法

要为DTO生成一个模式,请实例化Spiral\JsonSchemaGenerator\Generator并调用generate方法,传入DTO类作为参数(完全限定类名或反射)。该方法将返回一个Spiral\JsonSchemaGenerator\Schema实例。

让我们创建一个简单的数据传输对象

namespace App\DTO;

use Spiral\JsonSchemaGenerator\Attribute\Field;

class Movie
{
    public function __construct(
        #[Field(title: 'Title', description: 'The title of the movie')]
        public readonly string $title,
        #[Field(title: 'Year', description: 'The year of the movie')]
        public readonly int $year,
        #[Field(title: 'Description', description: 'The description of the movie')]
        public readonly ?string $description = null,
        public readonly ?string $director = null,
        #[Field(title: 'Release Status', description: 'The release status of the movie')]
        public readonly ?ReleaseStatus $releaseStatus = null,
    ) {
    }
}

此DTO有一个名为releaseStatus的枚举。让我们创建它

namespace App\DTO;

enum ReleaseStatus: string
{
    case Released = 'Released';
    case Rumored = 'Rumored';
    case PostProduction = 'Post Production';
    case InProduction = 'In Production';
    case Planned = 'Planned';
    case Canceled = 'Canceled';
}

现在,让我们为这个DTO生成一个模式

use Spiral\JsonSchemaGenerator\Generator;
use App\DTO\Movie;

$generator = new Generator();
$schema = $generator->generate(Movie::class);

注意 此外,该包还提供了Spiral\JsonSchemaGenerator\GeneratorInterface,可以将其集成到您的应用程序的依赖容器中,以便进行进一步的自定义和灵活性。

Spiral\JsonSchemaGenerator\Schema对象实现了JsonSerializable接口,允许轻松地将模式转换为JSON或PHP数组。

示例数组输出

[
    'properties'  => [
        'title'         => [
            'title'       => 'Title',
            'description' => 'The title of the movie',
            'type'        => 'string',
        ],
        'year'          => [
            'title'       => 'Year',
            'description' => 'The year of the movie',
            'type'        => 'integer',
        ],
        'description'   => [
            'title'       => 'Description',
            'description' => 'The description of the movie',
            'type'        => 'string',
        ],
        'director'      => [
            'type' => 'string',
        ],
        'releaseStatus' => [
            'title'       => 'Release Status',
            'description' => 'The release status of the movie',
            'allOf'       => [
                [
                    '$ref' => '#/definitions/ReleaseStatus',
                ],
            ],
        ],
    ],
    'required'    => [
        'title',
        'year',
    ],
    'definitions' => [
        'ReleaseStatus' => [
            'title' => 'ReleaseStatus',
            'type'  => 'string',
            'enum'  => [
                'Released',
                'Rumored',
                'Post Production',
                'In Production',
                'Planned',
                'Canceled',
            ],
        ],
    ],
];

类属性可以是数组,可以使用PHPDoc注释指定数组内元素的类型。

例如,我们有一个包含对象数组的DTO

namespace App\DTO;

use Spiral\JsonSchemaGenerator\Attribute\Field;

final class Actor
{
    public function __construct(
        public readonly string $name,
        /**
         * @var array<Movie>
         */
        public readonly array $movies = [],
    ) {
    }
}

在这个例子中,我们使用PHPDoc块来指示属性$movies包含一个Movie对象的数组。

注意 支持各种文档类型注释,包括@var array< Movie >@var Movie[]@var list< Movie >。对于推荐属性,您可以使用如@param array< Movie > $movies@param Movie[] $movies@param list< Movie > $movies之类的注释。

现在,让我们为这个DTO生成一个模式

use Spiral\JsonSchemaGenerator\Generator;
use App\DTO\Actor;

$generator = new Generator();
$schema = $generator->generate(Actor::class);

示例数组输出

[
    'properties' => [
        'name'   => [
            'type' => 'string',
        ],
        'movies' => [
            'type'  => 'array',
            'items' => [
                '$ref' => '#/definitions/Movie',
            ],
            'default' => [],
        ],
    ],
    'required'   => [
        'name',
    ],
    'definitions' => [
        'Movie'         => [
            'title'      => 'Movie',
            'type'       => 'object',
            'properties' => [
                'title'         => [
                    'title'       => 'Title',
                    'description' => 'The title of the movie',
                    'type'        => 'string',
                ],
                'year'          => [
                    'title'       => 'Year',
                    'description' => 'The year of the movie',
                    'type'        => 'integer',
                ],
                'description'   => [
                    'title'       => 'Description',
                    'description' => 'The description of the movie',
                    'type'        => 'string',
                ],
                'director'      => [
                    'type' => 'string',
                ],
                'releaseStatus' => [
                    'title'       => 'Release Status',
                    'description' => 'The release status of the movie',
                    'allOf'       => [
                        [
                            '$ref' => '#/definitions/ReleaseStatus',
                        ],
                    ],
                ],
            ],
            'required'   => [
                'title',
                'year',
            ],
        ],
        'ReleaseStatus' => [
            'title' => 'ReleaseStatus',
            'type'  => 'string',
            'enum'  => [
                'Released',
                'Rumored',
                'Post Production',
                'In Production',
                'Planned',
                'Canceled',
            ],
       ]
    ],
];

测试

composer test

变更日志

有关最近更改的更多信息,请参阅CHANGELOG

贡献

有关详细信息,请参阅CONTRIBUTING

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件