"дискриминатор" в полиморфизме, OpenAPI 2.0 (Swagger 2.0)

Ссылка на OpenAPI 2.0, объект схемы или Swagger 2.0, объект схемы и определение discriminator поле как:

Добавлена ​​поддержка полиморфизма. Дискриминатор - это имя свойства схемы, которое используется для различения других схем, которые наследуют эту схему. Используемое имя свойства ДОЛЖНО быть определено в этой схеме, и оно ДОЛЖНО быть в required список свойств. При использовании значение ДОЛЖНО быть именем этой схемы или любой схемы, которая ее наследует.

Мои заблуждения / вопросы:

  • Мне неоднозначно, какую именно роль он играет в наследовании или полиморфизме. Может кто-нибудь объяснить, пожалуйста discriminator с рабочим примером, показывающим, что именно он делает, и что, если мы его не используем? Любые ошибки, предупреждения или какие-либо инструменты, которые зависят от этого для некоторых операций?
  • Это тот случай, когда Swagger-редактор не поддерживает discriminator, а это поле используется в некоторых других инструментах?

Что я уже пробовал:

  • Я попытался использовать swagger-editor и пример из той же документации (также упомянутой ниже), чтобы поиграть с этим свойством, чтобы увидеть, вижу ли я какое-либо из его специальных поведений. Я изменил свойство, удалил его и расширил Dog Модель на один уровень глубже и попробовал то же самое на новой подмодели, но я не увидел никаких изменений в предварительном просмотре Swagger-редактора.
  • Я пытался искать в Интернете, и особенно вопросы stackru, но не нашел никакой соответствующей информации.

Пример кода, который я использовал для экспериментов:

definitions:
  Pet:
    type: object
    discriminator: petType
    properties:
      name:
        type: string
      petType:
        type: string
    required:
    - name
    - petType
  Cat:
    description: A representation of a cat
    allOf:
    - $ref: '#/definitions/Pet'
    - type: object
      properties:
        huntingSkill:
          type: string
          description: The measured skill for hunting
          default: lazy
          enum:
          - clueless
          - lazy
          - adventurous
          - aggressive
      required:
      - huntingSkill
  Dog:
    description: A representation of a dog
    allOf:
    - $ref: '#/definitions/Pet'
    - type: object
      properties:
        packSize:
          type: integer
          format: int32
          description: the size of the pack the dog is from
          default: 0
          minimum: 0
      required:
      - packSize

2 ответа

Решение

Согласно этой группе Google, discriminator используется поверх allOf свойство и оно определено в супер типе для полиморфизма. Если discriminator не используется, allOf Ключевое слово описывает, что модель содержит свойства других моделей для композиции.

Как в вашем примере кода, Pet супер тип со свойством petType определены как discriminator а также Cat это подтип Pet, Ниже приводится пример JSON Cat объект:

{
  "petType": "Cat",
  "name": "‎Kitty"
}

Использование discriminator намеревается указать свойство, используемое для идентификации типа объекта. Предполагается, что существуют инструменты, которые могут надлежащим образом поддерживать объекты определений с использованием discriminator, можно определить тип путем сканирования свойства. Например, определить объект является Cat в соответствии с petType,

Тем не менее discriminator поле не очень хорошо определено в спецификации текущей версии или в примерах (см. выпуск № 403). Насколько я знаю, в настоящее время Swagger не предоставляет никаких инструментов, которые бы должным образом его поддерживали.

discriminator может использоваться, если модель имеет свойство, используемое для определения типа. В этом случае он естественным образом подходит и может использоваться в качестве индикатора для понимания другими разработчиками взаимосвязи полиморфизма. Если сторонние инструменты, такие как ReDoc, которые поддерживают discriminator (увидеть petType в этом gif и примере), вы можете найти это полезным.

Функциональность дискриминатора была значительно улучшена в OpenApi 3. Теперь вы предоставляете объект дискриминатора, который содержит имя свойства дискриминатора, а также сопоставление значений этого свойства с именами схемы.

(Я понимаю, что вы спрашивали об OpenApi 2, но в 3 он настолько улучшился, что, надеюсь, вы сможете его использовать).

См.: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#discriminatorObject для актуальной спецификации

Другие вопросы по тегам