Generate JSON Schema files from your Eloquent models for Laravel applications.
- Single Source of Truth: Infer schema from model casts, database columns, PHPDoc types, and PHP Attributes
- Request & Response Schemas: Generate different schemas for API requests and responses
- Composable Resolvers: Modular system for extracting schema information
- PHP Attributes: Clean metadata injection with custom attributes
- Validation Integration: Middleware for automatic request validation
- OpenAPI Support: Export schemas for Swagger/Redoc documentation
- Versioning: Track schema changes with version management
- Artisan Commands: Easy generation, diffing, and publishing
composer require onamfc/eloquent-json-schemaPublish the configuration file:
php artisan vendor:publish --provider="onamfc\EloquentJsonSchema\LaravelSchemaServiceProvider"use App\Schemas as S;
#[S\SchemaName('User')]
#[S\RequestOnly(['password'])]
class User extends Model {
#[S\Title('User ID')]
#[S\Format('uuid')]
public $id;
#[S\Description('Primary email')]
#[S\Format('email')]
public $email;
#[S\Enum(['basic','pro','enterprise'])]
public $plan;
}# Generate all model schemas
php artisan schema:generate
# Generate specific model
php artisan schema:generate UserRoute::post('/users', [UserController::class, 'store'])
->middleware('schema:User.request');Schemas are saved to storage/api-schemas/{version}/models/:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://schemas.example.com/v1/models/User.response.schema.json",
"title": "User",
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid", "readOnly": true },
"email": { "type": "string", "format": "email" },
"plan": { "type": "string", "enum": ["basic","pro","enterprise"] }
},
"required": ["id","email","plan"]
}#[SchemaName('CustomName')]- Override model name in schema#[Title('Field Title')]- Add title to property#[Description('Field description')]- Add description to property#[Format('email|uuid|date-time')]- Set format constraint#[Enum(['value1', 'value2'])]- Define enum values#[RequestOnly(['field1'])]- Fields only in request schema#[ResponseOnly(['field1'])]- Fields only in response schema
# Generate schemas
php artisan schema:generate
# Show differences between versions
php artisan schema:diff --from=v1 --to=v2
# Export OpenAPI components
php artisan schema:publish-openapiKey configuration options in config/laravel-schema.php:
- version: Schema version identifier
- output_directory: Where to save generated schemas
- type_mapping: How to map database types to JSON Schema
- relationship_depth: Whether to embed relationships or use ID references
- decimal_as: Handle decimals as 'number' or 'string'
Register the middleware in your HTTP kernel:
protected $middlewareAliases = [
'schema' => \onamfc\EloquentJsonSchema\Http\Middleware\ValidateWithSchemaMiddleware::class,
];Use in routes:
Route::post('/api/users', [UserController::class, 'store'])
->middleware('schema:User.request');Export schemas as OpenAPI components:
php artisan schema:publish-openapiThen reference in your OpenAPI spec:
paths:
/users:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserRequest'
responses:
201:
content:
application/json:
schema:
$ref: '#/components/schemas/UserResponse'MIT License