Skip to content
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

Polymorphic serializer - type field example instead of "string" #1322

Open
avacaru opened this issue Oct 31, 2024 · 1 comment
Open

Polymorphic serializer - type field example instead of "string" #1322

avacaru opened this issue Oct 31, 2024 · 1 comment

Comments

@avacaru
Copy link

avacaru commented Oct 31, 2024

Currently the rest_polymorphic extension generates OAS components looking like this:

components:
  schemas:
    MyComponentTyped:
      allOf:
      - type: object
        properties:
          type:
            type: string
        required:
        - type
      - $ref: '#/components/schemas/MyComponent'

When viewing this with Swagger UI or Redoc, the type field's example is just "string", which is quite confusing if you don't know what the actual type should be.

I've looked over the rest_polymorphic extension source code and I think that a potential change would be to update the resource_type_schema to something like:

resource_type_schema = build_object_type(
    properties={resource_type_field_name: {**build_basic_type(OpenApiTypes.STR), "example": resource_type}},
    required=None if patched else [resource_type_field_name]
)

Where resource_type is a new argument to the build_typed_component() method.

I'm not sure if this is the right approach, I've also tried fixing this using the @extend_schema_serializer decorator, but as mentioned in #649 it is not straight forward and I didn't get too far.

I'd appreciate any insight on how to go about this, thanks!

@tfranzel
Copy link
Owner

tfranzel commented Nov 4, 2024

Hi, I think I get your point but you leave out an important detail. The Typed components are not used in isolation. They are always paired with a discriminator, which kind of indirectly specifies what is supposed to be used:

    NomadicPerson:
      type: object
      properties:
        id:
          type: integer
          readOnly: true
        address:
          type: string
          readOnly: true
          maxLength: 30
      required:
      - address
      - id
    NomadicPersonTyped:
      allOf:
      - type: object
        properties:
          resourcetype:
            type: string
        required:
        - resourcetype
      - $ref: '#/components/schemas/NomadicPerson'
    Person:
      oneOf:
      - $ref: '#/components/schemas/LegalPersonTyped'
      - $ref: '#/components/schemas/NaturalPersonTyped'
      - $ref: '#/components/schemas/NomadicPersonTyped'
      discriminator:
        propertyName: resourcetype
        mapping:
          legal: '#/components/schemas/LegalPersonTyped'
          natural: '#/components/schemas/NaturalPersonTyped'
          nomadic: '#/components/schemas/NomadicPersonTyped'

This is the recommended way of modelling the discriminator and works quite well with code generators: https://swagger.io/docs/specification/v3_0/data-models/inheritance-and-polymorphism/

Also, there is not really a good (and portable) way to describe a "fixed" values in OpenAPI 3.0. I think this was made easier in 3.1. This would be the basic requirement to ever consider changing anything.

Describing this as an example value might sneak it into the SwaggerUI but this does not seem to be too dependable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants