basillangevin/laravel-data-json-schemas
Composer 安装命令:
composer require basillangevin/laravel-data-json-schemas
包简介
Transforms Spatie Data objects into JSON Schemas with built-in validation
README 文档
README
This package transforms spatie/laravel-data classes into JSON Schemas and includes built-in validation.
Table of Contents
Click to expand
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
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<Data> $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<Data> $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<Data> $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<Data> $dataClass */ JsonSchema::collect(string $dataClass): BasilLangevin\LaravelDataJsonSchemas\Schemas\ArraySchema;
JsonSchema::toArray(...)
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(...)
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
This package supports the title, description, and default JSON Schema annotations.
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
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
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
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
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 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 | ✅ | ||||
| ✅ | |||||
| 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
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
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
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
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.
basillangevin/laravel-data-json-schemas 适用场景与选型建议
basillangevin/laravel-data-json-schemas 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 33.66k 次下载、GitHub Stars 达 13, 最近一次更新时间为 2025 年 02 月 08 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「laravel」 「laravel-data」 「BasilLangevin」 「laravel-data-json-schemas」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 basillangevin/laravel-data-json-schemas 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 basillangevin/laravel-data-json-schemas 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 basillangevin/laravel-data-json-schemas 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A Scribe Plugin to generate API doc from spatie/laravel-data
Add authorization to your data
Generate JSON Schemas from Laravel Data objects with validation attributes
Free Scramble extension for automatic OpenAPI schema generation from spatie/laravel-data classes
Alfabank REST API integration
Laravel package for URL value objects, sanitization pipelines, browser URL support, validation rules, request macros, and Laravel Data integration.
统计信息
- 总下载量: 33.66k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 13
- 点击次数: 11
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-02-08