Cameron Ball
Cameron Ball

Reputation: 4108

Making a PHP Object from a JSON Schema

I've been tasked with creating a class for objects defined by a JSON schema. Initially I was just going to build the class based on the schema, but now I've been told it should be automatically generated from the schema itself.

I want the class to have set/get methods for its members.

What's the best way to go about this?

Upvotes: 4

Views: 6886

Answers (3)

Everett
Everett

Reputation: 9558

Please note that the package below is abandoned and no longer maintained. No replacement package was suggested.


I wrote a package for this use case: https://packagist.org/packages/dto/dto

The idea was to be able to define objects as JSON schema so that other services could consume the definitions, and then use those same JSON schemas to define the PHP objects internally.

<?php
class Example extends Dto\Dto
{
   protected $schema = [
        'type' => 'object',
        'properties' => [
            'a' => ['type' => 'string'],
            'b' => ['type' => 'string']
        ],
        'additionalProperties' => false
    ];
}

A couple things are tricky with this package (and being strict with types in PHP in general):

  1. PHP does not have magic methods for __toInt et al. So if you are using a value in your DTO object in a place that requires data of a certain type, e.g. comparing it with an integer, you have to explicitly resolve the value to the type.

if ($dto->my_integer > 3) { // generates an error!

instead, you have to explicitly convert the value to a scalar value (as defined by your JSON Schema definition):

if ($dto->my_integer->toScalar() > 3) { // works

  1. Often your JSON Schemas have various required fields -- so if you instantiate an object that is defined by that schema, you must hydrate it via the construct, otherwise it's in an invalid state. I found it helpful to have a few variants of the schemas, e.g. to allow for an empty unhydrated object for less-restrictive PHP use, and it's helpful when supporting various HTTP verbs -- e.g. the GET request may return only part of an object, a POST request will require some fields, a PATCH request may require a unique id field and at least one other field, etc.

Hope this helps.

Upvotes: 0

vearutop
vearutop

Reputation: 4062

Using swaggest/php-code-builder you can generate PHP classes with accessor methods and validation during mapping.

Mapping and validation is powered by swaggest/json-schema, a fast and compatible JSON schema implementation.

Produced classes are IDE-friendly, so you'll have auto completion for all properties.

Upvotes: 4

Ross McFarlane
Ross McFarlane

Reputation: 4254

I think you have a couple of options here.

  1. Code Generation: Run through the schema and build the PHP code up as a string. This would be quite quick, but you'd have to be happy with using the generated output as-is, otherwise you'll be in trouble if the schema changes.
  2. Build an object that holds the schema and uses __call() to intercept calls to getFoo() or setBar() and can perform the necessary validation and return values.

In both cases, I think the tricky part will be if you meet reference types along the way. If your schema is fairly simple, though, it shouldn't be too bad.

Good luck!

Upvotes: -1

Related Questions