rushing/laravel-data-schemas

Generate JSON Schemas from Laravel Data objects with validation attributes

dev-main 2025-09-30 12:32 UTC

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 to typescript: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

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.