Gera classes de modelo PHP a partir de arquivos JSON-Schema, incluindo validação e fornecimento de preenchimento automático fluente para as classes geradas.
Exemplo simples de um aplicativo PHP: você define e documenta uma API com anotações swagger e modelos JSON-Schema. Agora você deseja usar modelos nas ações do controlador, em vez de acessar manualmente os dados da solicitação (por exemplo, coisas do array). Além disso, seu esquema já define as regras de validação para os modelos. Por que duplicar essas regras em seu código escrito manualmente? Em vez disso, você pode configurar um middleware que instancie modelos gerados com esta biblioteca e alimente o modelo com os dados da solicitação. Agora você tem um modelo validado que pode usar na ação do controlador. Com preenchimento automático completo ao trabalhar com objetos aninhados. Yay!
A maneira recomendada de instalar o php-json-schema-model-generator é através do Composer:
$ composer require --dev wol-soft/php-json-schema-model-generator
$ composer require wol-soft/php-json-schema-model-generator-production
Para evitar adicionar todas as dependências do php-json-schema-model-generator às suas dependências de produção, é recomendado adicionar a biblioteca como uma dependência de desenvolvimento e incluir a biblioteca wol-soft/php-json-schema-model-generator-production . A biblioteca de produção fornece todas as classes para executar o código gerado. A geração das classes deve ser uma etapa realizada no ambiente de desenvolvimento ou como uma etapa de construção do seu aplicativo (que é o fluxo de trabalho recomendado).
Confira os documentos para mais detalhes.
O objeto base para geração de modelos é o ModelGenerator . Depois de criar um Gerador, você poderá usar o objeto para gerar suas classes de modelo sem qualquer configuração adicional:
( new ModelGenerator ())
-> generateModels ( new RecursiveDirectoryProvider ( __DIR__ . ' /schema ' ), __DIR__ . ' /result ' );
O primeiro parâmetro do método generateModels deve ser uma classe que implementa SchemaProviderInterface . O provedor busca os arquivos de esquema JSON e os fornece ao gerador. Os seguintes provedores estão disponíveis:
Provedor | Descrição |
---|---|
Provedor de diretório recursivo | Busca todos os arquivos *.json do diretório de origem fornecido. Cada arquivo deve conter uma definição de objeto do esquema JSON no nível superior |
Provedor OpenAPIv3 | Busca todos os objetos definidos na #/components/schemas section de um arquivo de especificação Open API v3 |
O segundo parâmetro deve apontar para um diretório existente e vazio (você pode usar o método auxiliar generateModelDirectory
para criar seu diretório de destino). Este diretório conterá as classes PHP geradas após a conclusão do gerador.
Como parâmetro opcional você pode configurar um objeto GeneratorConfiguration (confira na documentação todas as opções disponíveis) para configurar seu Gerador e/ou usar o método generateModelDirectory para gerar seu diretório de modelo (irá gerar o diretório se ele não existir; se existir, todos os arquivos e pastas contidos serão removidos para um processo de geração limpo):
$ generator = new ModelGenerator (
( new GeneratorConfiguration ())
-> setNamespacePrefix ( ' MyAppModel ' )
-> setImmutable ( false )
);
$ generator
-> generateModelDirectory ( __DIR__ . ' /result ' );
-> generateModels ( new RecursiveDirectoryProvider ( __DIR__ . ' /schema ' ), __DIR__ . ' /result ' );
O gerador verificará recursivamente o diretório de origem fornecido e converterá todos os arquivos *.json encontrados em modelos. Todos os arquivos JSON-Schema dentro do diretório de origem devem fornecer um esquema de um objeto.
O diretório ./tests/manual
contém alguns exemplos fáceis que mostram o uso. Após instalar as dependências da biblioteca via composer update
você pode executar php ./tests/manual/test.php
para gerar os exemplos e brincar com alguns arquivos JSON-Schema para explorar a biblioteca.
Vamos dar uma olhada em um exemplo fácil. Criamos um modelo simples para uma pessoa com nome e idade opcional. Nosso esquema JSON resultante:
{
"$id" : " Person " ,
"type" : " object " ,
"properties" : {
"name" : {
"type" : " string "
},
"age" : {
"type" : " integer " ,
"minimum" : 0
}
},
"required" : [
" name "
]
}
Após gerar uma classe com este JSON-Schema nossa classe com o nome Person
fornecerá a seguinte interface:
// the constructor takes an array with data which is validated and applied to the model
public function __construct( array $ modelData );
// the method getRawModelDataInput always delivers the raw input which was provided on instantiation
public function getRawModelDataInput(): array ;
// getters to fetch the validated properties. Age is nullable as it's not required
public function getName(): string ;
public function getAge(): ? int ;
// setters to change the values of the model after instantiation (only generated if immutability is disabled)
public function setName( string $ name ): Person ;
public function setAge(? int $ age ): Person ;
Agora vamos dar uma olhada no comportamento do modelo gerado:
// Throws an exception as the required name isn't provided.
// Exception: 'Missing required value for name'
$ person = new Person ([]);
// Throws an exception as the name provides an invalid value.
// Exception: 'Invalid type for name. Requires string, got int'
$ person = new Person ([ ' name ' => 12 ]);
// Throws an exception as the age contains an invalid value due to the minimum definition.
// Exception: 'Value for age must not be smaller than 0'
$ person = new Person ([ ' name ' => ' Albert ' , ' age ' => - 1 ]);
// A valid example as the age isn't required
$ person = new Person ([ ' name ' => ' Albert ' ]);
$ person -> getName (); // returns 'Albert'
$ person -> getAge (); // returns NULL
$ person -> getRawModelDataInput (); // returns ['name' => 'Albert']
// If setters are generated the setters also perform validations.
// Exception: 'Value for age must not be smaller than 0'
$ person -> setAge (- 10 );
Mensagens de exceção mais complexas, por exemplo. de uma composição allOf pode ser semelhante a:
Invalid value for Animal declined by composition constraint.
Requires to match 3 composition elements but matched 1 elements.
- Composition element #1: Failed
* Value for age must not be smaller than 0
- Composition element #2: Valid
- Composition element #3: Failed
* Value for legs must not be smaller than 2
* Value for legs must be a multiple of 2
O processo de geração de classes basicamente se divide em três a quatro etapas:
A biblioteca é testada via PHPUnit.
Após instalar as dependências da biblioteca via composer update
você pode executar os testes com ./vendor/bin/phpunit
(Linux) ou vendorbinphpunit.bat
(Windows). Os nomes dos testes são otimizados para o uso da saída --testdox
. A maioria dos testes são testes de integração atômica que irão configurar um arquivo JSON-Schema e gerar uma classe a partir do esquema e testar o comportamento da classe gerada posteriormente.
Durante a execução os testes criarão um diretório PHPModelGeneratorTest em tmp onde serão gravados os arquivos JSON-Schema e as classes PHP.
Se um teste que cria uma classe PHP a partir de um esquema JSON falhar, o esquema JSON e as classes geradas serão despejadas no diretório ./failed-classes
A documentação da biblioteca é gerada com o Sphinx.
Para gerar a documentação de instalação do Sphinx, entre no diretório docs e execute make html
(Linux) ou make.bat html
(Windows). A documentação gerada estará disponível no diretório ./docs/build
.
A documentação hospedada em Read the Docs é atualizada a cada push.