Skip to content

Conversation

@butschster
Copy link
Member

@butschster butschster commented Aug 20, 2025

This PR implements dedicated constraint attributes that work alongside the existing Field attribute to provide modular, composable JSON Schema validation. Instead of bloating the Field attribute with validation concerns, this creates focused, single-purpose attributes that can be combined for powerful validation rules.

🚀 Features

New Constraint Attributes

  • #[Pattern(regex)] - String pattern validation with regex
  • #[Length(min, max)] - String/array length constraints
  • #[Range(min, max, exclusiveMin, exclusiveMax)] - Numeric range validation
  • #[MultipleOf(value)] - Numeric multiple validation
  • #[Items(min, max, unique)] - Array item constraints
  • #[Enum(values)] - Enumeration validation

💡 Usage Examples

Basic Constraints

final class User
{
    public function __construct(
        #[Field(title: 'Full Name')]
        #[Pattern('^[A-Z][a-z]+(?: [A-Z][a-z]+)*$')]
        #[Length(min: 2, max: 100)]
        public string $name,

        #[Field(title: 'Age')]
        #[Range(min: 13, max: 120)]
        public int $age,

        #[Field(title: 'Price')]
        #[Range(min: 0.01, max: 99999.99)]
        #[MultipleOf(0.01)]
        public float $price,
    ) {}
}

Array and Enum Constraints

final class Post
{
    public function __construct(
        #[Field(title: 'Tags')]
        #[Items(min: 1, max: 10, unique: true)]
        public array $tags,

        #[Field(title: 'Status')]
        #[Enum(['draft', 'published', 'archived'])]
        public string $status,
    ) {}
}

Mixed with PHPDoc Constraints

final class Product
{
    public function __construct(
        /** @var positive-int */ // PHPDoc constraint
        #[Range(max: 1000)] // Attribute constraint
        public int $quantity, // Results in: minimum: 1, maximum: 1000
    ) {}
}

📊 Generated JSON Schema

The above examples generate clean, standards-compliant JSON Schema:

{
  "type": "object",
  "properties": {
    "name": {
      "title": "Full Name",
      "type": "string",
      "pattern": "^[A-Z][a-z]+(?: [A-Z][a-z]+)*$",
      "minLength": 2,
      "maxLength": 100
    },
    "tags": {
      "title": "Tags", 
      "type": "array",
      "minItems": 1,
      "maxItems": 10,
      "uniqueItems": true
    },
    "status": {
      "title": "Status",
      "type": "string",
      "enum": ["draft", "published", "archived"]
    }
  },
  "required": ["name", "tags", "status"]
}

- Add modular constraint attributes: Pattern, Length, Range, MultipleOf, Items, Enum
- Create AttributeConstraintExtractor for attribute-to-validation-rule conversion
- Add comprehensive test
@butschster butschster requested a review from roxblnfk August 20, 2025 18:57
@butschster butschster self-assigned this Aug 20, 2025
@butschster butschster added the enhancement New feature or request label Aug 20, 2025
@butschster butschster linked an issue Aug 20, 2025 that may be closed by this pull request
- Introduce PropertyDataExtractorInterface for validation constraint extraction
- Add CompositePropertyDataExtractor with fluent API for extractor composition
- Refactor AttributeConstraintExtractor and ValidationConstraintExtractor to implement new interface
@butschster butschster merged commit 39720e4 into 2.x Aug 20, 2025
5 checks passed
@butschster butschster deleted the issue/16 branch August 20, 2025 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create Dedicated Constraint Attributes for JSON Schema Validation

2 participants