Skip to content

Add class-level Definition and AdditionalProperty attributes #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: 2.x
Choose a base branch
from

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.
@butschster butschster changed the base branch from 1.x to 2.x April 19, 2025 10:36
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
Status: No status
Development

Successfully merging this pull request may close these issues.

1 participant