PHPackages                             basillangevin/laravel-data-json-schemas - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. basillangevin/laravel-data-json-schemas

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

basillangevin/laravel-data-json-schemas
=======================================

Transforms Spatie Data objects into JSON Schemas with built-in validation

v1.3.1(3mo ago)1336.0k—7.4%3[1 issues](https://github.com/BasilLangevin/laravel-data-json-schemas/issues)[5 PRs](https://github.com/BasilLangevin/laravel-data-json-schemas/pulls)1MITPHPPHP ^8.3CI passing

Since Feb 8Pushed 1w ago1 watchersCompare

[ Source](https://github.com/BasilLangevin/laravel-data-json-schemas)[ Packagist](https://packagist.org/packages/basillangevin/laravel-data-json-schemas)[ Docs](https://github.com/basillangevin/laravel-data-json-schemas)[ GitHub Sponsors](https://github.com/BasilLangevin)[ RSS](/packages/basillangevin-laravel-data-json-schemas/feed)WikiDiscussions main Synced 3d ago

READMEChangelog (5)Dependencies (30)Versions (15)Used By (1)

Laravel Data classes to JSON Schemas
====================================

[](#laravel-data-classes-to-json-schemas)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d61f8d746a57f28c86b87c9f30ff416efda7321af5d3a24656a8b2242981914b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f626173696c6c616e676576696e2f6c61726176656c2d646174612d6a736f6e2d736368656d61732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/basillangevin/laravel-data-json-schemas)[![GitHub Tests Action Status](https://camo.githubusercontent.com/8e0f72f29955fbdabb7b4496866c958c0f5cf12910648eab9ec2593477f75361/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f626173696c6c616e676576696e2f6c61726176656c2d646174612d6a736f6e2d736368656d61732f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/basillangevin/laravel-data-json-schemas/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/a10212239e1da21052fcc1147879d368525ba591e15be613e9f186ca59e8eb3c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f626173696c6c616e676576696e2f6c61726176656c2d646174612d6a736f6e2d736368656d61732f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/basillangevin/laravel-data-json-schemas/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/2130824a672d059c7061489412c4a4af08513d731664300350f84c9892eb218a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f626173696c6c616e676576696e2f6c61726176656c2d646174612d6a736f6e2d736368656d61732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/basillangevin/laravel-data-json-schemas)

This package transforms [spatie/laravel-data](https://github.com/spatie/laravel-data) classes into JSON Schemas and includes built-in validation.

Table of Contents
-----------------

[](#table-of-contents)

Click to expand- [Installation](#installation)
- [Quick start](#quick-start)
    - [JsonSchema::toArray(...)](#jsonschematoarray)
    - [JsonSchema::collectToArray(...)](#jsonschemacollecttoarray)
- [Schema annotations](#schema-annotations)
    - [Setting the title](#setting-the-title)
    - [Setting the description](#setting-the-description)
    - [Setting the default value](#setting-the-default-value)
- [Validation rules](#validation-rules)
    - [Supported validation attributes](#supported-validation-attributes)
    - [Date attribute transformations](#date-attribute-transformations)
- [Type transformations](#type-transformations)
- [Testing](#testing)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [Security Vulnerabilities](#security-vulnerabilities)
- [Credits](#credits)
- [License](#license)

Installation
------------

[](#installation)

> **Note:** This package requires PHP 8.3+ and Laravel 11+.

You can install the package via composer:

```
composer require basillangevin/laravel-data-json-schemas
```

Optionally, you can publish the config file with:

```
php artisan vendor:publish --tag="laravel-data-json-schemas-config"
```

This is the contents of the published config file:

```
use BasilLangevin\LaravelDataJsonSchemas\Enums\JsonSchemaDialect;

return [
    /*
    |--------------------------------------------------------------------------
    | JSON Schema Dialect
    |--------------------------------------------------------------------------
    |
    | If this value is not null, a "$schema" keyword will be set to
    | this identifier in the root of each generated JSON Schema.
    | This value won't change how JSON Schemas are generated.
    */
    'dialect' => JsonSchemaDialect::Draft201909,
];
```

Quick start
-----------

[](#quick-start)

The `BasilLangevin\LaravelDataJsonSchemas\DataSchemas` facade can transform any `Spatie\LaravelData\Data` class into a JSON Schema.

It includes four methods:

```
/**
 * Transform a Spatie Data class into a JSON Schema.
 *
 * @param  class-string  $dataClass
 */
JsonSchema::toArray(string $dataClass): array;

/**
 * Transform a Spatie Data class into an array schema.
 * The "items" will be instances of the Data class.
 *
 * @param  class-string  $dataClass
 */
JsonSchema::collectToArray(string $dataClass): array;

/**
 * Transform a Spatie Data class into a JSON Schema object.
 * The object can then be modified with keyword methods.
 *
 * @param  class-string  $dataClass
 */
JsonSchema::make(string $dataClass): BasilLangevin\LaravelDataJsonSchemas\Schemas\ObjectSchema;

/**
 * Transform a Spatie Data class into an ArraySchema object.
 * The object can then be modified with keyword methods.
 *
 * @param  class-string  $dataClass
 */
JsonSchema::collect(string $dataClass): BasilLangevin\LaravelDataJsonSchemas\Schemas\ArraySchema;
```

### JsonSchema::toArray(...)

[](#jsonschematoarray)

To demonstrate transforming a `Data` class into a JSON Schema, we'll create a simple `BikeData` class:

```
use Spatie\LaravelData\Attributes\Validation\In;
use Spatie\LaravelData\Attributes\Validation\Min;
use Spatie\LaravelData\Data;

class BikeData extends Data
{
    public function __construct(
        public string $brand,
        /** The model name of the bike. */
        public string $model,
        #[Min(2010)]
        public int $year,
        #[In(['red', 'blue', 'green'])]
        public ?string $color = null,
        public bool $is_electric = false,
    ) {}
}
```

Now, we can transform this `Data` class into a JSON Schema (as a PHP array):

```
$schema = JsonSchema::toArray(BikeData::class);
```

This will generate the following JSON Schema. As you can see, the JSON Schema includes descriptions and validation rules to match each property's doc block and attributes:

```
$schema = [
    '$schema' => 'https://json-schema.org/draft/2019-09/schema',
    'title' => 'Bike',
    'type' => 'object',
    'properties' => [
        'brand' => [
            'type' => 'string',
        ],
        'model' => [
            'type' => 'string',
            'description' => 'The model name of the bike.',
        ],
        'year' => [
            'type' => 'integer',
            'minimum' => 2010,
        ],
        'color' => [
            'default' => null,
            'type' => ['string', 'null'],
            'enum' => ['red', 'blue', 'green'],
        ],
        'is_electric' => [
            'default' => false,
            'type' => 'boolean',
        ],
    ],
    'required' => ['brand', 'model', 'year', 'is_electric'],
];
```

### JsonSchema::collectToArray(...)

[](#jsonschemacollecttoarray)

We can also transform `Data` classes into a JSON Schema array whose items are instances of the `Data` class:

```
$schema = JsonSchema::collectToArray(BikeData::class);
```

This will generate the following JSON Schema:

```
$schema = [
    '$schema' => 'https://json-schema.org/draft/2019-09/schema',
    'items' => [
        'title' => 'Bike',
        'type' => 'object',
        'properties' => [
            ...
        ],
        'required' => ['brand', 'model', 'year', 'is_electric'],
    ],
];
```

Schema annotations
------------------

[](#schema-annotations)

This package supports the `title`, `description`, and `default` JSON Schema annotations.

### Setting the title

[](#setting-the-title)

`Data` classes and their properties can have a JSON Schema `title` annotation which can be set three different ways (in order of precedence):

**1. Using the `BasilLangevin\LaravelDataJsonSchemas\Attributes\Title` attribute:**

```
#[Title('The title of a data class.')]
class BikeData extends Data
{
    public function __construct(
        #[Title('The title of a property.')]
        public string $brand,
    ) {}
}
```

**2. Using the summary of a PHPDoc block (when it also has a description):**

> **Note:** This method is not currently supported on Windows Servers.

```
/**
 * The title of a data class.
 *
 * The description of a data class.
 */
class BikeData extends Data
{
    public function __construct(
        /**
         * The title of a property.
         *
         * The description of a property.
         */
        public string $brand,
    ) {}
}
```

**3. Using the name of the `Data` class:**

The class name will be used as the `title` if no other title is set. Any "Data" suffix will be removed, and the name will be title-cased and space-separated.

For example, `BikePartData` will become `Bike Part`.

### Setting the description

[](#setting-the-description)

`Data` classes and their properties can have a JSON Schema `description` annotation which can be set four different ways (in order of precedence):

**1. Using the `BasilLangevin\LaravelDataJsonSchemas\Attributes\Description` attribute:**

```
#[Description('The description of a data class.')]
class BikeData extends Data
{
    public function __construct(
        #[Description('The description of a property.')]
        public string $brand,
    ) {}
}
```

**2. Using the description of an `@param` or `@var` tag of a PHPDoc block:**

```
/**
 * @var string $model The description of the model property.
 */
class BikeData extends Data
{
    public function __construct(
        /** @param string $brand The description of the brand property. */
        public string $brand,
        public string $model,
    ) {}
}
```

**3. Using the summary of a PHPDoc block (when it has no description):**

> **Note:** This method is not currently supported on Windows Servers.

```
/**
 * The description of a data class.
 */
class BikeData extends Data
{
    /**
     * The description of a property.
     */
    public string $brand;
}
```

**4. Using the description of a PHPDoc block (when it also has a summary):**

> **Note:** This method is not currently supported on Windows Servers.

```
/**
 * The title of a data class.
 *
 * The description of a data class.
 */
class BikeData extends Data
{
    /**
     * The title of a property.
     *
     * The description of a property.
     */
    public string $brand;
}
```

### Setting the default value

[](#setting-the-default-value)

The `default` JSON Schema annotation will be set to the default value of the property.

```
class BikeData extends Data
{
    public function __construct(
        public string $brand = 'Trek',
    ) {}
}
```

Validation rules
----------------

[](#validation-rules)

This package automatically transforms `spatie\laravel-data` validation attributes into JSON Schema keywords.

For example, the `Min` attribute will be transformed into a `minLength` keyword when the property is a string or a `minimum` keyword when the property is an integer:

```
use Spatie\LaravelData\Attributes\Validation\Min;

class BikeData extends Data
{
    public function __construct(
        #[Min(3)]
        public string $name,
        #[Min(10)]
        public int $quantity,
    ) {}
}

$schema = JsonSchema::toArray(BikeData::class);
```

This will generate the following JSON Schema:

```
$schema = [
    '$schema' => 'https://json-schema.org/draft/2019-09/schema',
    'title' => 'Bike',
    'type' => 'object',
    'properties' => [
        'name' => [
            'minLength' => 3,
        ],
        'quantity' => [
            'minimum' => 10,
        ],
    ],
];
```

### Supported validation attributes

[](#supported-validation-attributes)

This package supports most of the validation attributes available in `spatie\laravel-data`, as detailed in the table below. Custom validation attributes are not supported.

Validation attributes that can be transformed into JSON Schema validation keywords are indicated with ✅.

Because JSON Schema's validation keywords are somewhat limited, some validation attributes can only be transformed into custom annotations (indicated with ☑️). These attributes cannot be validated by any JSON Schema validator, so they must be validated by Laravel's validation system.

Finally, some validation attributes are not supported at all (indicated with ❌). Typically, these attributes exceed the scope of what JSON Schema supports, or they rely on database calls to be validated.

The following table summarizes the support for each attribute, grouped by JSON Schema's `type` keyword rather than the PHP type equivalent.

See the [Type transformations](#type-transformations) section for more details.

**Attribute****string****number****array****object****boolean****Accepted**✅✅**AcceptedIf**❌❌**ActiveUrl**☑️**After**☑️**AfterOrEqual**☑️**Alpha**✅**AlphaDash**✅**AlphaNumeric**✅**ArrayType**✅**Bail**❌❌❌❌❌**Before**☑️**BeforeOrEqual**☑️**Between**✅✅✅✅**BooleanType**✅✅✅**Confirmed**☑️☑️☑️☑️☑️**CurrentPassword**❌**Date**✅**DateEquals**✅**DateFormat**☑️**Declined**✅✅✅**DeclinedIf**❌❌❌**Different**☑️**Digits**✅**DigitsBetween**✅**Dimensions**❌**Distinct**☑️☑️☑️☑️☑️**DoesntEndWith**✅**DoesntStartWith**✅**Email**✅**EndsWith**✅**Enum**✅✅**ExcludeIf**❌❌❌❌❌**ExcludeUnless**❌❌❌❌❌**ExcludeWith**❌❌❌❌❌**ExcludeWithout**❌❌❌❌❌**Exists**❌❌**File**❌**Filled**✅✅✅✅**GreaterThan**✅✅✅✅**GreaterThanOrEqualTo**✅✅✅✅**Image**❌**In**✅✅**InArray**❌❌❌**IntegerType**✅**IP**☑️**IPv4**✅**IPv6**✅**Json**☑️**LessThan**✅✅✅✅**LessThanOrEqualTo**✅✅✅✅**Lowercase**✅**ListType**❌**MacAddress**☑️**Max**✅✅✅✅**MaxDigits**✅**MimeTypes**❌**Mimes**❌**Min**✅✅✅✅**MinDigits**✅**MultipleOf**✅**NotIn**✅✅**NotRegex**✅**Nullable**✅✅✅✅✅**Numeric**✅**Password**❌**Present**✅✅✅✅✅**Prohibited**✅✅✅✅**ProhibitedIf**❌❌❌❌**ProhibitedUnless**❌❌❌❌**Prohibits**❌❌❌❌**Regex**✅**Required**✅✅✅✅✅**RequiredIf**❌❌❌❌❌**RequiredUnless**❌❌❌❌❌**RequiredWith**❌❌❌❌❌**RequiredWithAll**❌❌❌❌❌**RequiredWithout**❌❌❌❌❌**RequiredWithoutAll**❌❌❌❌❌**RequiredArrayKeys**❌❌❌❌❌**Rule**❌❌❌❌❌**Same**☑️☑️☑️☑️☑️**Size**✅✅✅✅**Sometimes**❌❌❌❌❌**StartsWith**✅**StringType**❌**TimeZone**☑️**Unique**❌❌**Uppercase**✅**Url**✅**Ulid**☑️**Uuid**✅### Date attribute transformations

[](#date-attribute-transformations)

Every validation attribute that validates dates (except the `DateFormat` attribute) sets the `format` keyword to `date-time`. Therefore, all date attributes follow the ISO 8601 standard.

Relative date attribute values (e.g. `'now'`, `'yesterday'`, `'next week'`, etc.) are transformed into ISO 8601 date strings.

Type transformations
--------------------

[](#type-transformations)

JSON Schema only supports a few types (`array`, `boolean`, `integer`, `number`, `object`, `string`, and `null`), so this package transforms PHP types into the closest JSON Schema type.

The following types are transformed as follows. All other types are currently unsupported.

**Array**Arrays are transformed into the `array` or `object` type depending on whether they have sequential integer keys.

**Boolean**Booleans are transformed into the `boolean` type.

**Collection**`Collection` types (including `DataCollection`) are transformed into the `array` type.

**Data**`Data` classes are transformed into `object` types.

**DateTimeInterface**`DateTimeInterface` types (including `DateTime`, `Carbon`, and `CarbonImmutable`) are transformed into the `string` type.

All date schemas include the `format` keyword with the value `date-time`. Therefore, all dates follow the ISO 8601 standard.

**Enum**Backed enums are transformed into either the `string` or `integer` type depending on their backing type. Pure enums are not supported.

**Float**Floats are transformed into the `number` type.

**Integer**Integers are transformed into the `integer` type.

**Null**Nulls are transformed into the `null` type.

**Object**Objects are transformed into the `object` type.

**String**Strings are transformed into the `string` type.

**Union**Unions are transformed into a union of their constituent types. Unions that include `Data` types wrap their constituent type schemas in an `anyOf` schema. Otherwise, the constituent schemas are consolidated into a single schema.

Testing
-------

[](#testing)

Each PHP file in this package has a co-located Pest test file named `{FileName}Test.php`.

This package also has integration tests in the `tests/Integration` directory. These integration tests are used to test complex `Data` class transformations including nested `Data` classes, collections of `Data` objects, recursive `Data` structures, and complex union types.

This package achieves 100% test coverage, 100% mutation coverage, and 100% PHPStan coverage coverage at level 10.

The following commands can be used to test the package:

```
# Run the standard test suite
./vendor/bin/pest --parallel

# Run the test suite and generate a coverage report
./vendor/bin/pest --coverage --parallel

# Run mutation tests
./vendor/bin/pest --mutate --parallel --covered-only

# Run PHPStan at level 10
./vendor/bin/phpstan analyse
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](./SECURITY.md) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [BasilLangevin](https://github.com/BasilLangevin)
- [All Contributors](https://github.com/BasilLangevin/laravel-data-json-schemas/graphs/contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

54

—

FairBetter than 96% of packages

Maintenance88

Actively maintained with recent releases

Popularity39

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 89.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~67 days

Recently: every ~0 days

Total

7

Last Release

106d ago

Major Versions

v1.1.0 → v12.x-dev2026-03-19

v1.2.0 → v13.x-dev2026-03-19

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/109987292?v=4)[Basil Langevin](/maintainers/BasilLangevin)[@BasilLangevin](https://github.com/BasilLangevin)

---

Top Contributors

[![BasilLangevin](https://avatars.githubusercontent.com/u/109987292?v=4)](https://github.com/BasilLangevin "BasilLangevin (133 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (7 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (7 commits)")[![gregpriday](https://avatars.githubusercontent.com/u/1126859?v=4)](https://github.com/gregpriday "gregpriday (2 commits)")

---

Tags

laravellaravel-dataBasilLangevinlaravel-data-json-schemas

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/basillangevin-laravel-data-json-schemas/health.svg)

```
[![Health](https://phpackages.com/badges/basillangevin-laravel-data-json-schemas/health.svg)](https://phpackages.com/packages/basillangevin-laravel-data-json-schemas)
```

###  Alternatives

[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.1k11.2M100](/packages/dedoc-scramble)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M47](/packages/spatie-laravel-pdf)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.6k](/packages/rawilk-profile-filament-plugin)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

44855.7k](/packages/harris21-laravel-fuse)[danestves/laravel-polar

A package to easily integrate your Laravel application with Polar.sh

8120.4k](/packages/danestves-laravel-polar)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24857.5k](/packages/vormkracht10-laravel-mails)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
