DEV Community

howyi
howyi

Posted on

๐Ÿ—Show Dev: json-schema-mapper - JSON Schema convert to jsonSerializable PHP classes

โญ

GitHub logo howyi / json-schema-mapper

JSON Schema Object|Enum to PHP classes




motivation

I am tired of making a PHP class that matches Json-schema anymore ๐Ÿ˜ต

install

$ composer require howyi/json-schema-mapper

usage

Specify the target JSON directory and the map (PHP) directory and namespace and execute

$ ./vendor/bin/jsm map [jsonDir] [phpDir] [namespace] [templatePath]

description

A library that generates PHP classes that can be acquired from JSON Schema with \json_encode()

Convert JSON Schema type to PHP type as much as possible and do type hint

When "type is string and format is date-time", the type hint becomes \ DateTimeInterface and when converting the array automatically performs ->format(\ DateTime::RFC3339)

The object specified by $ ref is converted to a type hint to the mapped interface

Enum is generated alone as an Enum class that inherits Eloquent\AbstractEnumration

example

directory

JSON dir

sample/json/
  โ”œ neta.json
  โ”œ osakanaType.json
  โ”œ shari.json
  โ”” sushi.json

Converted PHP dir

sample/generated/
  โ”œ Neta/
  โ”‚  โ”œ Neta.php
  โ”‚  โ”œ NetaInterface.php
  โ”‚  โ”” NetaTrait.php
  โ”œ Shari/
  โ”‚  โ”œ Shari.php
  โ”‚  โ”œ ShariInterface.php
  โ”‚  โ”” ShariTrait.php
  โ”œ Sushi/
  โ”‚  โ”œ Sushi.php
  โ”‚  โ”œ SushiInterface.php
  โ”‚  โ”” SushiTrait.php
  โ”” OsakanaType.php

file

JSON (sushi.json)

{
  "title": "ๅฏฟๅธๆƒ…ๅ ฑ",
  "type": "object",
  "properties": {
    "sushiId": {
      "title": "ๅฏฟๅธID",
      "type": "integer"
    },
    "sushiName": {
      "title": "ๅฏฟๅธใฎๅๅ‰",
      "type": "string"
    },
    "eatable": {
      "title": "้ฃŸในใ‚‰ใ‚Œใ‚‹ใ‹",
      "type": "boolean"
    },
    "length": {
      "title": "ๅฏฟๅธใฎ้•ทใ•",
      "type": "number"
    },
    "osakanaType": {
      "title": "ใŠ้ญšใ‚ฟใ‚คใƒ—",
      "$ref": "osakanaType.json"
    },
    "neta": {
      "title": "ใƒใ‚ฟ",
      "$ref": "./neta.json"
    },
    "shari": {
      "title": "ใ‚ทใƒฃใƒช",
      "$ref": "./shari.json"
    },
    "expirationDate": {
      "title": "ๆถˆ่ฒปๆœŸ้™",
      "type": "string",
      "format": "date-time"
    }
  },
  "required": [
    "sushiId",
    "sushiName",
    "eatable",
    "osakanaType",
    "neta",
    "shari",
    "expirationDate"
  ],
  "additionalProperties": true
}

Converted PHP(Class)

<?php

namespace Json\Sushi;

use Json\OsakanaType;
use Json\Neta\NetaInterface;
use Json\Shari\ShariInterface;

class Sushi implements SushiInterface
{
    use SushiTrait;

    protected $sushiId;
    protected $sushiName;
    protected $eatable;
    protected $length;
    protected $osakanaType;
    protected $neta;
    protected $shari;
    protected $expirationDate;
    protected $additionalProperties;

    public function __construct(
        int $sushiId,
        string $sushiName,
        bool $eatable,
        ?float $length,
        OsakanaType $osakanaType,
        NetaInterface $neta,
        ShariInterface $shari,
        \DateTimeInterface $expirationDate,
        array $additionalProperties = []
    ) {
        $this->sushiId = $sushiId;
        $this->sushiName = $sushiName;
        $this->eatable = $eatable;
        $this->length = $length;
        $this->osakanaType = $osakanaType;
        $this->neta = $neta;
        $this->shari = $shari;
        $this->expirationDate = $expirationDate;
        $this->additionalProperties = $additionalProperties;
    }

    public function sushiId(): int
    {
        return $this->sushiId;
    }

    public function sushiName(): string
    {
        return $this->sushiName;
    }

    public function eatable(): bool
    {
        return $this->eatable;
    }

    public function length(): ?float
    {
        return $this->length;
    }

    public function osakanaType(): OsakanaType
    {
        return $this->osakanaType;
    }

    public function neta(): NetaInterface
    {
        return $this->neta;
    }

    public function shari(): ShariInterface
    {
        return $this->shari;
    }

    public function expirationDate(): \DateTimeInterface
    {
        return $this->expirationDate;
    }

    public function additionalProperties(): array
    {
        return $this->additionalProperties;
    }
}

Converted PHP(Trait)

<?php

namespace Json\Sushi;

trait SushiTrait
{
    use \JsonSchemaMapper\ObjectTrait;

    public function jsonProperties(): array
    {
        return [
            'sushiId',
            'sushiName',
            'eatable',
            'length',
            'osakanaType',
            'neta',
            'shari',
            'expirationDate',
        ];
    }

    public function allowAdditionalProperties(): bool
    {
        return true;
    }
}

Converted PHP(Interface)

<?php

namespace Json\Sushi;

use JsonSchemaMapper\JsonArrayAccess;
use Json\Neta\NetaInterface;
use Json\OsakanaType;
use Json\Shari\ShariInterface;

interface SushiInterface extends JsonArrayAccess, \JsonSerializable
{
    public function toJsonArray(): array;

    public function jsonProperties(): array;

    public function allowAdditionalProperties(): bool;

    public function sushiId(): int;

    public function sushiName(): string;

    public function eatable(): bool;

    public function length(): ?float;

    public function osakanaType(): OsakanaType;

    public function neta(): NetaInterface;

    public function shari(): ShariInterface;

    public function expirationDate(): \DateTimeInterface;

    public function additionalProperties(): array;
}

Top comments (0)