schematic icon indicating copy to clipboard operation
schematic copied to clipboard

(NOT MAINTAINED) Generate POPO from JSON Schema

Schematic

Latest Stable Version License Build Status Code Coverage Scrutinizer Code Quality

THIS PROJECT IS NOT MAINTAINED.

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 rwos/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