martinstarecek/schematic

Generate POPO from JSON Schemas

0.9.0 2018-09-13 12:22 UTC

This package is auto-updated.

Last update: 2024-11-14 02:56:59 UTC


README

Latest Stable Version License Build Status Code Coverage Scrutinizer Code Quality

Schematic is a JSON Schema parser that also supports Plain Old PHP Object (POPO) code generation. These generated models can either be used for as a starting point for domain entities or simply provide additional structure for JSON request bodies.

Strives for PSR-1, PSR-2, and PSR-4 compliance.

Install

composer require martinstarecek/schematic

Examples

The example/ directory contains a number of examples.

Schema Parsing

Given the following schema in car.json:

{
    "type": "object",
    "properties": {
        "make": {
            "type": "string"
        },
        "model": {
            "type": "string"
        },
        "year": {
            "type": "integer"
        },
        "owners": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "isCurrentOwner": {
                        "type": "boolean"
                    }
                },
                "required": ["name"]
            }
        }
    },
    "required": ["make", "model"]
}

First the schema needs to be parsed:

use RoundingWell\Schematic\Schema;

$schema = Schema::fromFile('car.json');

assert($schema->isObject());

When the schema is an object the properties can be accessed:

$properties = $schema->properties();

assert(is_array($properties));
assert(isset($properties['make']));
assert(isset($properties['owners']));

And can be checked for required properties:

assert($schema->isRequired('make'));
assert($schema->isRequired('year') === false);

Array items provide additional details about contents:

$items = $properties['owners']->items();

assert($items->isObject());

Code Generation

Generated classes are extremely basic, plain PHP objects from schemas.

use RoundingWell\Schematic\Generator;

$generator = new Generator();

The generator can create an AST from an object schema, as well as additional classes for object properties.

$classes = $generator->generate($schema, 'Acme\Model\Car', 'Acme\Model');

This will create an Acme\Model\Car class that extends Acme\Model. Any object properties in the schema will also be created. Once the classes have been generated they can be written to a directory:

$files = $generator->write($classes, 'src/');

The writer will convert the AST into code, write to src/, and return the files that were created.

Complete Example

Putting it all together, here is a complete example for code generation:

use RoundingWell\Schematic\Generator;
use RoundingWell\Schematic\Schema;

$generator = new Generator();
$schema = Schema::fromFile('car.json');
$classes = $generator->generate($schema);
$files = $generator->write($classes, 'src/', 'Acme\Model');

Note: The last parameter to write() the PSR-4 namespace of your project. When provided, this namespace will be removed from the file path.

The source of src/Car.php will be:

<?php

namespace Acme\Model;

class Car
{
    /**
     * @var string
     */
    public $vin;
    /**
     * @var string|null
     */
    public $make;
    /**
     * @var string|null
     */
    public $model;
    /**
     * @var int|null
     */
    public $year;
    /**
     * @var \Acme\Model\Car\Owner[]
     */
    public $owners;
}

And the source of src/Car/Owner.php will be:

<?php

namespace Acme\Model\Car;

class Owner
{
    /**
     * @var string
     */
    public $name;
    /**
     * @var bool|null
     */
    public $isCurrentOwner;
}

Recommendations

Models generated by Schematic do not include functionality to populate the model from JSON. We recommend using using JsonMapper or a similar hydrator.

License

Apache 2.0