Skip to content

SchemaGenerator

Viames Marino edited this page Feb 23, 2026 · 1 revision

Pair framework: SchemaGenerator

Pair\Api\OpenApi\SchemaGenerator generates OpenAPI/JSON Schema definitions from ActiveRecord models and DB metadata.

When to use

Use SchemaGenerator to keep API schemas aligned with current model binds/table definitions and to avoid manual schema drift.

Main methods

generate(string $modelClass): array

Builds full object schema from table description and model binds.

generateCreateSchema(string $modelClass, array $rules = []): array

Builds create-request schema:

  • removes auto fields (createdAt, updatedAt, ...)
  • removes auto-increment key fields
  • optionally uses validation rules to define required fields and allowed properties

generateUpdateSchema(string $modelClass, array $rules = []): array

Builds update schema from create schema, with all fields optional.

Type mapping behavior

Maps MySQL column types to OpenAPI types/formats (integer, number/float, string/date-time, boolean, object, binary).

Also handles:

  • tinyint(1) -> boolean
  • enum -> string with enum
  • set -> array of enum strings
  • nullable columns -> union with null
  • defaults -> typed default values
  • auto-increment/virtual columns -> readOnly: true

Implementation example

use Pair\Api\OpenApi\SchemaGenerator;

$g = new SchemaGenerator();

$itemSchema = $g->generate(App\Models\Faq::class);
$createSchema = $g->generateCreateSchema(App\Models\Faq::class, [
    'question' => 'required|string|min:3',
    'answer' => 'required|string|min:3',
]);
$updateSchema = $g->generateUpdateSchema(App\Models\Faq::class, [
    'question' => 'string|min:3',
    'answer' => 'string|min:3',
]);

Notes

  • Uses Database::describeTable() and model getBinds().
  • Uses TABLE_KEY to identify key fields.

Frequent usage recipes

Generate component schemas for docs build

$g = new \Pair\Api\OpenApi\SchemaGenerator();

$components = [
    'User' => $g->generate(\App\Orm\User::class),
    'Order' => $g->generate(\App\Orm\Order::class),
];

Generate create/update request body schemas from validation rules

$create = $g->generateCreateSchema(\App\Orm\Order::class, [
    'customerId' => 'required|int',
    'total' => 'required|numeric|min:0.01',
]);

$update = $g->generateUpdateSchema(\App\Orm\Order::class, [
    'total' => 'numeric|min:0.01',
    'note' => 'string|max:500',
]);

Common pitfalls

  • Assuming generated schema enforces all business logic constraints.
  • Using stale DB metadata in environments with unapplied migrations.
  • Forgetting nullable/default semantics when adding custom schema overrides.

See also: SpecGenerator, Database, ActiveRecord.

Clone this wiki locally