2017 © Pedro Peláez
 

library schema

Parse and generate data schema formats

image

psx/schema

Parse and generate data schema formats

  • Monday, April 9, 2018
  • by k42b3
  • Repository
  • 4 Watchers
  • 28 Stars
  • 22,026 Installations
  • PHP
  • 5 Dependents
  • 0 Suggesters
  • 9 Forks
  • 0 Open issues
  • 46 Versions
  • 14 % Grown

The README.md

Schema

This library helps you to work with fully typed objects, it provides the following features:, (*1)

  • Transform raw JSON data into fully typed objects
  • Parse PHP classes into a TypeSchema specification
  • Generate DTOs in different languages like TypeScript, Java, C# etc.

We provide also a hosted version of this code generator. For more integration options you can also take a look at the SDKgen project which provides a CLI binary or GitHub action to integrate the code generator., (*2)

Object mapper

This example reads raw JSON data and transform it into the provided Person class., (*3)

$json = <<<'JSON'
{
    "firstName": "Ludwig",
    "lastName": "Beethoven",
    "age": 254
}
JSON;

$objectMapper = new ObjectMapper(new SchemaManager());

$person = $objectMapper->readJson($json, SchemaSource::fromClass(Person::class));

assert('Ludwig' === $person->getFirstName());
assert('Beethoven' === $person->getLastName());
assert(254 === $person->getAge());

$json = $objectMapper->writeJson($person);

Besides a simple class there are multiple ways to specify a source, for example to parse an array of persons s., (*4)

$json = <<<'JSON'
[
    {
        "firstName": "Ludwig",
        "lastName": "Beethoven",
        "age": 254
    }
]
JSON;

$objectMapper = new ObjectMapper(new SchemaManager());

$personList = $objectMapper->readJson($json, SchemaSource::fromType('array<Person>'));

assert(1 === count($personList));
assert('Ludwig' === $personList[0]->getFirstName());

$json = $objectMapper->writeJson($person);

Code generation

It is possible to transform any DTO class into a TypeSchema specification. This schema can then be used to generate DTOs in different languages which helps to work with type-safe objects across different environments., (*5)

$schemaManager = new SchemaManager();
$factory = new GeneratorFactory();

$schema = $schemaManager->getSchema(Person::class);

$generator = $factory->getGenerator(GeneratorFactory::TYPE_JAVA, Config::of('org.typeschema.model'));

$result = $generator->generate();

$result->writeTo('/my_model.zip');

TypeSchema specification

It is possible to transform an existing TypeSchema specification into a PHP DTO class. For example lets take a look at the following specification, which describes a person:, (*6)

{
  "definitions": {
    "Person": {
      "type": "struct",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "age": {
          "description": "Age in years",
          "type": "integer"
        }
      }
    }
  },
  "root": "Person"
}

It is then possible to turn this specification into a ready-to-use PHP class s., (*7)


$schemaManager = new SchemaManager(); $factory = new GeneratorFactory(); $schema = $schemaManager->getSchema(__DIR__ . '/my_schema.json'); $generator = $factory->getGenerator(GeneratorFactory::TYPE_PHP, Config::of('App\\Model')); $result = $generator->generate(); foreach ($result as $file => $code) { file_put_contents(__DIR__ . '/' . $file, '<?php' . "\n" . $code); }

This would result in the following PHP class:, (*8)

<?php

declare(strict_types = 1);

class Person implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $firstName = null;
    protected ?string $lastName = null;
    #[Description("Age in years")]
    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 toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('firstName', $this->firstName);
        $record->put('lastName', $this->lastName);
        $record->put('age', $this->age);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}

Every generated PHP class implements also the JsonSerializable interface so you can simply encode an object to json., (*9)

$person = new Person();
$person->setFirstName('foo');
$person->setLastName('bar');
$person->setAge(32);

echo json_encode($person);

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

Attributes

The following attributes are available:, (*10)

Attribute Target Example
Deprecated Property #[Deprecated(true)]
DerivedType Class #[DerivedType(Person::class, 'person')]
Description Class/Property #[Description("content")]
Discriminator Class #[Discriminator('type')]
Exclude Property #[Exclude]
Format Property #[Format('date-time')]
Key Property #[Key('my-complex-name')]
Nullable Property #[Nullable(true)]

The Versions

03/04 2016
03/04 2016
02/04 2016