Skip to content

Enum has allOf wrapper with single $ref value #1413

@rvinzent

Description

@rvinzent

Describe the bug

I am generating what I would think is a pretty standard enum field, but the generated schema has a useless allOf wrapper around the $ref and this causes some type issues on my client generator (fabrikt; giving up on OpenAPI Tools 😆 ), and the existing code seems like it intends to remove these allOf wrappers with a single value. For some reason, when switching to openapi version 3.1.0, the safe_ref behavior is not enabled.

This is causing the generator to interpret this as a string field instead of using an enum type.

To Reproduce

Serializers look something like this:

class MyObjectSerializer(serializers.Serializer):
    status = serializers.ChoiceField(Status.choices, default=Status.AVAILABLE)


class Status(models.TextChoices):
    AVAILABLE = "Available"

I also have some enum related configuration:

SPECTACULAR_SETTINGS = {
    "OAS_VERSION": "3.1.0",
    "ENUM_NAME_OVERRIDES": {
        "Status": "api.models.utils.constants.Status",
    },
  "ENUM_ADD_EXPLICIT_BLANK_NULL_CHOICE": False,
    "COMPONENT_SPLIT_REQUEST": True,
    "POSTPROCESSING_HOOKS": [
        "drf_spectacular.hooks.postprocess_schema_enums",
    ],

Expected behavior

I would expect the OpenAPI to look like this, and I've confirmed this fixes the generated client code.

MyObject:
  properties:
    status:
      $ref: '#/components/schemas/Status'
      default: Available

This schema is valid according to the JSON Schema reference linked out by the openapi spec.

Example valid JSON schema with $ref and default on the same level (link)

   {
       "title": "Feature list",
       "type": "array",
       "prefixItems": [
           {
               "title": "Feature A",
               "properties": {
                   "enabled": {
                       "$ref": "#/$defs/enabledToggle",
                       "default": true
                   }
               }
           },
        ]
    }

Instead, the openapi schema is generated with a useless wrapper around the $ref

MyObject:
  properties:
    status:
      allOf:
        - $ref: '#/components/schemas/Status'
      default: Available

I'm not sure if this is intentional or a bug, but it seemed like existing code was intending to remove the allOf wrapper.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions