rushing / laravel-data-schemas
Generate JSON Schemas from Laravel Data objects with validation attributes
Requires
- php: ^8.2
- illuminate/console: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
- spatie/laravel-data: ^4.0|^5.0
- symfony/finder: ^6.0|^7.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2025-09-30 12:32:43 UTC
README
Generate JSON Schemas from Laravel Data objects with validation attributes.
This package automatically converts your Spatie Laravel Data objects into JSON Schema files, preserving validation rules, descriptions, and examples. Perfect for AI-powered applications, API documentation, and frontend validation.
Features
- 🎯 Single Source of Truth: Define structure, validation, types, and schemas all in your Data objects
- 🔄 Automatic Generation: Run
schemas:generate
similar totypescript:transform
- 📝 Rich Metadata: Add descriptions and examples via custom attributes
- 🎨 Flexible Output: Configure path structure (namespace, flat, or custom)
- 🔌 Extensible: Custom collectors, generators, and path generators
- ✅ Validation Mapping: Automatic conversion of Spatie validation attributes to JSON Schema constraints
Installation
Install via Composer:
composer require rushing/laravel-data-schemas
Publish the configuration file (optional):
php artisan vendor:publish --tag=data-schemas-config
Usage
1. Add Attributes to Your Data Objects
<?php namespace App\Data; use Spatie\LaravelData\Data; use Spatie\LaravelData\Attributes\Validation\Max; use Spatie\LaravelData\Attributes\Validation\Email; use Rushing\LaravelDataSchemas\Attributes\Description; use Rushing\LaravelDataSchemas\Attributes\Example; class UserData extends Data { public function __construct( #[Description('User full name')] #[Example('John Doe')] #[Max(255)] public string $name, #[Description('User email address')] #[Example('john@example.com')] #[Email] public string $email, #[Description('User age in years')] #[Example(25)] #[Example(42)] public ?int $age = null, ) {} }
2. Generate JSON Schemas
# Generate all schemas php artisan schemas:generate # Generate for specific path php artisan schemas:generate --path=app/Data/Schemas # Generate for specific class php artisan schemas:generate --class="App\Data\UserData" # Override output directory php artisan schemas:generate --output=storage/schemas
3. Use Generated Schemas
// resources/schemas/App/Data/UserData.schema.json { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "UserData", "type": "object", "title": "UserData", "properties": { "name": { "type": "string", "description": "User full name", "examples": ["John Doe"], "maxLength": 255 }, "email": { "type": "string", "description": "User email address", "examples": ["john@example.com"], "format": "email" }, "age": { "type": ["integer", "null"], "description": "User age in years", "examples": [25, 42] } }, "required": ["name", "email"] }
Configuration
The config/data-schemas.php
file provides extensive configuration options:
return [ // Paths to scan for Data objects 'auto_discover_types' => [ app_path('Data'), ], // Filter by namespace patterns (optional) 'namespaces' => [ // 'App\\Data\\Schemas\\*', ], // Output directory 'output_directory' => resource_path('schemas'), // Path structure: 'namespace', 'flat', or 'custom' 'path_structure' => 'namespace', // Custom path generator callable 'custom_path_generator' => null, // Pretty print JSON 'format_output' => true, // JSON Schema version 'schema_version' => 'https://json-schema.org/draft/2020-12/schema', // Include $schema and $id 'schema_metadata' => [ '$schema' => true, '$id' => true, ], // Custom validation attribute mappings 'validation_mapping' => [], ];
Path Structure Options
Namespace Structure (default)
resources/schemas/
└── App/
└── Data/
└── UserData.schema.json
Flat Structure
resources/schemas/
├── UserData.schema.json
├── ProductData.schema.json
└── OrderData.schema.json
Custom Structure
'path_structure' => 'custom', 'custom_path_generator' => function (ReflectionClass $class, string $baseDir) { return $baseDir . '/api/' . $class->getShortName() . '.json'; },
Supported Validation Attributes
The package automatically maps Spatie validation attributes to JSON Schema constraints:
Validation Attribute | JSON Schema Constraint |
---|---|
#[Max(255)] |
maxLength (string), maximum (number), maxItems (array) |
#[Min(1)] |
minLength (string), minimum (number), minItems (array) |
#[Between(1, 100)] |
minimum + maximum |
#[Email] |
format: "email" |
#[Uuid] |
format: "uuid" |
#[Url] |
format: "uri" |
#[Enum(StatusEnum::class)] |
enum: [values] |
#[Nullable] |
type: ["string", "null"] |
Custom Attributes
Description
Add human-readable descriptions to properties or classes:
#[Description('User profile information')] class UserData extends Data { #[Description('Primary email address for notifications')] public string $email; }
Example
Add one or multiple examples (repeatable attribute):
#[Example('John Doe')] #[Example('Jane Smith')] public string $name;
Integration with Build Process
Add to your package.json
scripts:
{ "scripts": { "types:generate": "php artisan typescript:transform", "schemas:generate": "php artisan schemas:generate", "build": "npm run types:generate && npm run schemas:generate && vite build" } }
Advanced Usage
Custom Validation Mapping
Override or extend validation attribute mappings:
// config/data-schemas.php 'validation_mapping' => [ CustomValidationAttribute::class => function ($attr) { return ['pattern' => $attr->getPattern()]; }, ],
Custom Path Generator
Implement the PathGenerator
interface:
use Rushing\LaravelDataSchemas\PathGenerators\PathGenerator; class ApiPathGenerator implements PathGenerator { public function getSchemaPath(ReflectionClass $class): string { return resource_path('api/schemas/' . $class->getShortName() . '.json'); } }
Register in config:
'path_generator' => App\Generators\ApiPathGenerator::class,
Custom Generator
Implement the Generator
interface for custom schema formats:
use Rushing\LaravelDataSchemas\Generators\Generator; class OpenApiGenerator implements Generator { public function canGenerate(ReflectionClass $class): bool { // Your logic } public function generate(ReflectionClass $class): array { // Generate OpenAPI schema format } }
Requirements
- PHP 8.2+
- Laravel 11.0+ or 12.0+
- spatie/laravel-data 4.0+ or 5.0+
License
The MIT License (MIT). Please see License File for more information.
Credits
- Stephen Rushing
- Inspired by spatie/laravel-typescript-transformer
- Built for the Spatie Laravel Data ecosystem
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.