@@ -447,6 +447,184 @@ The generated schema will include a `oneOf` section to reflect the union types:
447447> All supported types are automatically resolved from native PHP type declarations and reflected in the JSON Schema
448448> output using oneOf.
449449
450+ ## Constraint Attributes
451+
452+ Generator supports dedicated constraint attributes that provide a clean, modular approach to validation rules.
453+
454+ ### Available Constraint Attributes
455+
456+ #### String Constraints
457+
458+ - ` #[Pattern(regex)] ` - Regular expression pattern validation
459+ - ` #[Length(min, max)] ` - String length constraints
460+
461+ #### Numeric Constraints
462+
463+ - ` #[Range(min, max, exclusiveMin, exclusiveMax)] ` - Numeric range validation with optional exclusive bounds
464+ - ` #[MultipleOf(value)] ` - Multiple of validation for numbers
465+
466+ #### Array Constraints
467+
468+ - ` #[Items(min, max, unique)] ` - Array item constraints with optional uniqueness
469+ - ` #[Length(min, max)] ` - Array length constraints (same attribute as strings, auto-detects type)
470+
471+ #### General Constraints
472+
473+ - ` #[Enum(values)] ` - Enumeration validation with array of allowed values
474+
475+ ### Usage Examples
476+
477+ #### String Validation
478+
479+ ``` php
480+ namespace App\DTO;
481+
482+ use Spiral\JsonSchemaGenerator\Attribute\Field;
483+ use Spiral\JsonSchemaGenerator\Attribute\Constraint\Pattern;
484+ use Spiral\JsonSchemaGenerator\Attribute\Constraint\Length;
485+
486+ final readonly class User
487+ {
488+ public function __construct(
489+ #[Field(title: 'Full Name', description: 'User full name in Title Case')]
490+ #[Pattern('^[A-Z][a-z]+(?: [A-Z][a-z]+)*$')]
491+ #[Length(min: 2, max: 100)]
492+ public string $name,
493+
494+ #[Field(title: 'Username')]
495+ #[Pattern('^[a-zA-Z0-9_]{3,20}$')]
496+ #[Length(min: 3, max: 20)]
497+ public string $username,
498+
499+ #[Field(title: 'Email', format: Format::Email)]
500+ #[Pattern('^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$')]
501+ public string $email,
502+ ) {}
503+ }
504+ ```
505+
506+ #### Numeric Validation
507+
508+ ``` php
509+ namespace App\DTO;
510+
511+ use Spiral\JsonSchemaGenerator\Attribute\Field;
512+ use Spiral\JsonSchemaGenerator\Attribute\Constraint\Range;
513+ use Spiral\JsonSchemaGenerator\Attribute\Constraint\MultipleOf;
514+
515+ final readonly class Product
516+ {
517+ public function __construct(
518+ #[Field(title: 'Price', description: 'Product price in USD')]
519+ #[Range(min: 0.01, max: 99999.99)]
520+ #[MultipleOf(0.01)]
521+ public float $price,
522+
523+ #[Field(title: 'Stock Quantity')]
524+ #[Range(min: 0, max: 10000)]
525+ public int $stock,
526+
527+ #[Field(title: 'Discount Percentage')]
528+ #[Range(min: 0, max: 100, exclusiveMax: true)]
529+ public float $discountPercent,
530+ ) {}
531+ }
532+ ```
533+
534+ #### Array and Enum Validation
535+
536+ ``` php
537+ namespace App\DTO;
538+
539+ use Spiral\JsonSchemaGenerator\Attribute\Field;
540+ use Spiral\JsonSchemaGenerator\Attribute\Constraint\Items;
541+ use Spiral\JsonSchemaGenerator\Attribute\Constraint\Length;
542+ use Spiral\JsonSchemaGenerator\Attribute\Constraint\Enum;
543+
544+ final readonly class BlogPost
545+ {
546+ public function __construct(
547+ #[Field(title: 'Tags', description: 'Post tags')]
548+ #[Items(min: 1, max: 10, unique: true)]
549+ public array $tags,
550+
551+ #[Field(title: 'Categories', description: 'Post categories')]
552+ #[Length(min: 1, max: 5)]
553+ public array $categories,
554+
555+ #[Field(title: 'Status')]
556+ #[Enum(['draft', 'published', 'archived', 'pending'])]
557+ public string $status,
558+
559+ #[Field(title: 'Priority')]
560+ #[Enum([1, 2, 3, 4, 5])]
561+ public int $priority,
562+ ) {}
563+ }
564+ ```
565+
566+ ### Generated Schema Output
567+
568+ The constraint attributes generate clean, standards-compliant JSON Schema validation rules:
569+
570+ ``` json
571+ {
572+ "type" : " object" ,
573+ "properties" : {
574+ "name" : {
575+ "title" : " Full Name" ,
576+ "description" : " User full name in Title Case" ,
577+ "type" : " string" ,
578+ "pattern" : " ^[A-Z][a-z]+(?: [A-Z][a-z]+)*$" ,
579+ "minLength" : 2 ,
580+ "maxLength" : 100
581+ },
582+ "price" : {
583+ "title" : " Price" ,
584+ "description" : " Product price in USD" ,
585+ "type" : " number" ,
586+ "minimum" : 0.01 ,
587+ "maximum" : 99999.99 ,
588+ "multipleOf" : 0.01
589+ },
590+ "tags" : {
591+ "title" : " Tags" ,
592+ "description" : " Post tags" ,
593+ "type" : " array" ,
594+ "minItems" : 1 ,
595+ "maxItems" : 10 ,
596+ "uniqueItems" : true
597+ },
598+ "status" : {
599+ "title" : " Status" ,
600+ "type" : " string" ,
601+ "enum" : [
602+ " draft" ,
603+ " published" ,
604+ " archived" ,
605+ " pending"
606+ ]
607+ }
608+ },
609+ "required" : [
610+ " name" ,
611+ " price" ,
612+ " tags" ,
613+ " status"
614+ ]
615+ }
616+ ```
617+
618+ ### Type Safety
619+
620+ Constraint attributes are automatically validated for type compatibility:
621+
622+ - ` Pattern ` only applies to string properties
623+ - ` Range ` and ` MultipleOf ` only apply to numeric properties (int, float)
624+ - ` Items ` constraints only apply to array properties
625+ - ` Length ` adapts behavior: ` minLength ` /` maxLength ` for strings, ` minItems ` /` maxItems ` for arrays
626+ - ` Enum ` works with any property type
627+
450628## PHPDoc Validation Constraints
451629
452630Generator supports extracting validation constraints from PHPDoc comments, providing rich validation
0 commit comments