Skip to content

[Platform] Allow renaming Structured Output JSON keys (e.g. Schema name / SerializedName) #2386

Description

@BriceFab

Description

Structured Output currently uses the PHP property name as the JSON Schema key, and the dedicated StructuredOutput\Serializer intentionally ignores Serializer naming metadata (#[SerializedName], name converters) so schema generation and hydration stay aligned (see #937 / #940).

That is a solid default, but there is no first-class way to expose a different JSON key to the model while keeping idiomatic PHP property names.

Example use case: PHP / domain code wants restBetweenRounds, but persisted JSON or an external contract already uses rest_between_rounds. Today the only options are:

  • rename the PHP property to match the JSON key (awkward in PHP), or
  • maintain custom mapping outside Symfony AI (easy to drift from the generated schema).

#[Schema] also has no name (or equivalent) argument today.

Proposed direction

One of (or a combination of):

  1. #[Schema(name: 'rest_between_rounds')] — used by the JsonSchema Factory as the property key in properties / required, and respected by the Structured Output serializer when denormalizing.
  2. Honor #[SerializedName] in both schema generation and the dedicated Structured Output serializer (same attribute as Symfony Serializer).
  3. Optional name converter / service injected into the JsonSchema Factory + Structured Output serializer (opt-in, default = current behavior: PHP property name).

Whatever the API, schema keys and hydration must stay in sync (the #937 lesson).

Benefits

  • Idiomatic camelCase PHP DTOs
  • Stable/snake_case (or legacy) JSON contracts for models / storage when needed
  • No custom mapping layers that can diverge from the generated schema

Example (illustrative)

final readonly class CircuitMetadata
{
    public function __construct(
        #[Schema(
            name: 'rest_between_rounds',
            description: 'Rest between rounds in seconds',
            minimum: 0,
        )]
        public int $restBetweenRounds,
    ) {}
}

Generated schema / model JSON would use rest_between_rounds; PHP keeps $restBetweenRounds.

Happy to discuss whether Schema(name: …), SerializedName, or an opt-in name converter is the preferred Symfony AI approach.

Metadata

Metadata

Assignees

No one assigned

    Labels

    PlatformIssues & PRs about the AI Platform componentRFCRFC = Request For Comments (proposals about features that you want to be discussed)Status: Waiting feedback

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions