Skip to content
This repository was archived by the owner on Sep 25, 2025. It is now read-only.

Conversation

butschster
Copy link

@butschster butschster commented Apr 19, 2025

This PR adds support for class-level schema definition through two new attributes:

New Features

  • Definition Attribute: A class-level attribute that provides core schema metadata:

    • title: Schema title
    • description: Schema description
    • id: Schema $id
    • schemaVersion: Schema version ($schema)
  • AdditionalProperty Attribute: A repeatable class-level attribute for adding any custom schema properties:

    • name: Property name
    • value: Property value (supports scalar, array, and object values)
  • Schema Class Updates:

    • Added methods for setting schema metadata (title, description, id, schemaVersion)
    • Added method for adding individual additional properties

Benefits

  1. Complete Schema Definition: Classes can now define all aspects of their JSON schema
  2. Better Standards Compliance: Support for $id and $schema properties aligns with JSON Schema specifications
  3. Custom Schema Extensions: Support for any custom properties through AdditionalProperty
  4. Clear Separation of Concerns: Core schema properties in Definition, custom properties in AdditionalProperty

Example Usage

#[Definition(
    title: 'Product Schema',
    description: 'A product in the catalog',
    id: 'https://example.com/schemas/product.json',
    schemaVersion: 'http://json-schema.org/draft-07/schema#'
)]
#[AdditionalProperty(name: 'additionalProperties', value: false)]
#[AdditionalProperty(name: 'examples', value: [
    [
        'id' => 123,
        'name' => 'Sample Product',
        'price' => 99.99,
        'inStock' => true
    ]
])]
class Product
{
    // Class properties with Field attributes
}

Support for PHP union types using oneOf in JSON Schema

This PR adds support for PHP 8.0+ union types (like string|int|bool) to the JSON Schema Generator. The implementation represents union types in JSON Schema using the standard oneOf construct.

Problem

Previously, the library couldn't properly handle PHP union types (string|int), which are a key feature of modern PHP typing. When generating JSON schemas from classes with union types, the schema wouldn't accurately represent these polymorphic types.

Solution

  • Added a new UnionType class to represent PHP union types
  • Created a TypeParser to extract and parse PHP reflection types
  • Modified the Property class to serialize union types using oneOf
  • Ensured the Generator properly handles all union type scenarios
  • Added comprehensive tests for all aspects of the implementation

Examples

PHP class with union types:

class UnionTypeExample
{
    public function __construct(
        public readonly string|int $stringOrInt,
        public readonly string|int|bool|null $multiType = null,
        public readonly ClassA|ClassB|null $objectUnion = null,
    ) {
    }
}

Generated JSON Schema:

{
  "properties": {
    "stringOrInt": {
      "oneOf": [
        { "type": "string" },
        { "type": "integer" }
      ]
    },
    "multiType": {
      "oneOf": [
        { "type": "string" },
        { "type": "integer" },
        { "type": "boolean" },
        { "type": "null" }
      ]
    },
    "objectUnion": {
      "oneOf": [
        { "$ref": "#/definitions/ClassA" },
        { "$ref": "#/definitions/ClassB" },
        { "type": "null" }
      ]
    }
  },
  "required": ["stringOrInt"]
}

- Add Definition attribute for class-level schema metadata
- Add AdditionalProperty attribute for custom schema properties
- Update Schema class to support metadata and additional properties
- Update Generator to process both new attributes
- Add comprehensive unit tests
- Add usage examples
@butschster butschster added the enhancement New feature or request label Apr 19, 2025
@butschster butschster self-assigned this Apr 19, 2025
…ool`) in the JSON Schema Generator. Union types are now properly represented in JSON Schema using the `oneOf` keyword.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

enhancement New feature or request

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant