Skip to content

[Question]: How to extend the library's behavior "the right way" ? #2579

@gnutix

Description

@gnutix

Hello there,

I've been working on upgrading the library from an old 4.x version to the latest 5.6.5, and I'm having a hard time understanding what's the proper way to extend/decorate/override/you-name-it the behavior of this (and swagger's ?) library.

Here's a few examples of custom stuff there is in the project :

  • Detect a specific Undefined class in a property's union type, then the property shouldn't be required (thanks to a custom (de)normalizer)
  • Detect specific PHP attributes on classes, and generate virtual properties for that class (API filters, sorting, pagination, stuff like that)
  • Detect properties having a specific PHP attribute and treat them differently (like #[AutoGeneratedId] public Id $id;)
  • Add "example" property to Enums with the value of the first case (just for nicer doc)
  • One specific Enum needs an additional "x-some-flag" property (for post-processing in typescript code generation)
  • Describe maps (array with string keys) as objects (not sure why it's not done by the library itself ?)
  • Detect classes having a specific parent class and add "virtual" properties with examples

At first, it seems like nothing really complicated or fancy. So I've added attributes where it's just static documentation, or created custom Describer (when needing reflection) or Processor (when post-processing the finalized schema itself).

And it mostly works... until it doesn't. Some stupid stuff really: add a #[Ignore] attribute or a Symfony Constraint on a property, and suddenly one of the custom behaviors listed above doesn't work anymore. Or #[OA\Schema] attributes don't work on some classes/enums, and I just don't understand why (probably it's bypassed by some Describer, but that's just a guess). Or I want to have two separate Describers to deal with "all Enums" (adding "example" property) and "one specific Enum" (adding x-some-flag), but I just can't get it to work and end up having to mix the logic for both in one describer with and use an instanceof check for the specific Enum... Anyway. Stuff like that tells me I'm probably doing it wrong in some (subtle or not) ways.

I tried to find some documentation (or AI help) about how this library should be used to extend it but couldn't find a clear answer anywhere (there's not even one occurrence of "Describer" in the official doc, which I find quite surprising). It's not even really clear to me where lies Swagger's responsibility versus this library's when it comes to generating the OpenAPI JSON spec file.

And I'm especially lost when it comes to having these extensions work recursively / in a nested fashion. Should we decorate Nelmio's describers ? What should we put in the supports() method ? Does it stop after it find the first describer supporting, or does it chain them, or else ? ...

Any help/explanation will be greatly appreciated.
Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions