psx/schema

解析和生成数据架构格式

v6.4.1 2024-09-22 20:59 UTC

README

此库可以从JSON文件或使用反射和属性从PHP类解析TypeSchema规范。基于此架构,它可以生成源代码并将原始JSON数据转换为DTO对象。通过这种方式,您可以在API中处理完全类型化的对象,用于入站和出站数据。它基本上提供以下功能:

  • 将原始JSON数据转换为DTO对象
  • 根据架构生成源代码(例如PHP、TypeScript)
  • 根据提供的架构验证数据

用法

首先,我们需要使用TypeSchema规范描述我们的数据格式。然后我们可以根据此规范生成相应的PHP类。

{
  "definitions": {
    "Person": {
      "type": "object",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "age": {
          "description": "Age in years",
          "type": "integer",
          "minimum": 0
        }
      },
      "required": [
        "firstName",
        "lastName"
      ]
    }
  },
  "$ref": "Person"
}

要生成PHP类,我们使用以下命令

vendor/bin/schema schema:parse --format=php schema.json

注意您也可以跳过此步骤,直接自行编写PHP类。从JSON表示开始的优势在于您以中性格式定义了模型,因此可以生成不同环境的模型,例如使用TypeScript生成器为前端生成模型。该命令生成以下源代码

<?php

declare(strict_types = 1);

#[Required(["firstName", "lastName"])]
class Person implements \JsonSerializable
{
    protected ?string $firstName = null;
    protected ?string $lastName = null;
    #[Description("Age in years")]
    #[Minimum(0)]
    protected ?int $age = null;
    public function setFirstName(?string $firstName) : void
    {
        $this->firstName = $firstName;
    }
    public function getFirstName() : ?string
    {
        return $this->firstName;
    }
    public function setLastName(?string $lastName) : void
    {
        $this->lastName = $lastName;
    }
    public function getLastName() : ?string
    {
        return $this->lastName;
    }
    public function setAge(?int $age) : void
    {
        $this->age = $age;
    }
    public function getAge() : ?int
    {
        return $this->age;
    }
    public function jsonSerialize()
    {
        return (object) array_filter(array('firstName' => $this->firstName, 'lastName' => $this->lastName, 'age' => $this->age), static function ($value) : bool {
            return $value !== null;
        });
    }
}

现在我们可以解析原始JSON数据并将其填充到我们的对象模型中

// the data which we want to import
$data = json_decode('{"firstName": "foo", "lastName": "bar"}');

$schemaManager = new SchemaManager();

// we read the schema from the class
$schema = $schemaManager->getSchema(Person::class);

try {
    $person = (new SchemaTraverser())->traverse($data, $schema, new TypeVisitor());
    
    // $example contains now an instance of the Person class containing 
    // the firstName and lastName property
    echo $person->getFirstName();

} catch (\PSX\Schema\Exception\ValidationException $e) {
    // the validation failed
    echo $e->getMessage();
}

每个生成的PHP类都实现了JsonSerializable接口,因此您可以简单地将对象编码为json。

$schema = new Person();
$schema->setFirstName('foo');
$schema->setLastName('bar');
$schema->setAge(12);

echo json_encode($schema);

// would result in
// {"firstName": "foo", "lastName": "bar", "age": 12}

生成器

除了PHP类之外,此库还可以生成以下类型:

  • CSharp
  • Go
  • GraphQL
  • HTML
  • Java
  • JsonSchema
  • Kotlin
  • Markdown
  • PHP
  • Protobuf
  • Python
  • Ruby
  • Rust
  • Swift
  • TypeSchema
  • TypeScript
  • VisualBasic

属性

以下属性可用: