Как определить разные параметры тела для одного и того же пути в OpenAPI (Swagger)?

У меня есть служба, которая может иметь два разных типа параметров тела на основе заголовка Content-Type.

Например. для пути /Pet:

  • Если используется Content-Type: application/somecustom.resource+json, то POST может принимать Pet в качестве параметра тела.

  • Если используется Content-Type: application/somecustom.function+json, то POST должен принимать какой-то другой параметр тела, чтобы вызвать функцию и вернуть другой ответ.

Любое предложение о том, как это проявить в OpenAPI (Swagger)?


person Optional    schedule 15.02.2016    source источник


Ответы (2)


OpenAPI 3.0 поддерживает разные схемы для каждого типа носителя.

openapi: 3.0.0
...
paths:
  /pet:
    post:
      requestBody:
        required: true
        content:
          application/somecustom.resource+json:
            schema:
              $ref: '#/components/schemas/Pet'
          application/somecustom.function+json:
            schema:
              $ref: '#/components/schemas/Foo'
person Helen    schedule 14.12.2017

Нет, невозможно определить два разных параметра тела для одной и той же операции в одном элементе пути. Имя элемента пути уникально, поскольку является именами свойств (и, следовательно, «ключами» в карте значений ключей JSON), а спецификация Swagger позволяет не более одного параметра тела в данной операции.

Есть несколько альтернативных подходов к решению этой проблемы:

Создайте два отдельных элемента пути

Например:

/pets/createFromDescription:
  post:
    summary: Create a pet from a basic description
    operationId: createPetFromDescription
    parameters:
      - name: petDescription
        in: body
        required: true
        schema:
          $ref: "#/definitions/PetDescriptionObject"
    responses:
      200:
        description: OK
/pets/createFromCatalog:
  post:
    summary: Create a pet from a standard catalog entry
    operationId: createPetFromCatalogEntry
    parameters:
      - name: petCatalogEntry
        in: body
        required: true
        schema:
          $ref: "#/definitions/PetCatalogEntry"
    responses:
      200:
        description: OK

Создавайте подтипы с помощью дискриминатора

Описано в спецификации Swagger – OpenAPI 2.0 здесь.

Пример:

/pets:
  post:
    summary: Create a pet 
    operationId: createPet
    parameters:
      - name: petSource
        in: body
        description: Structured pet information, from which to create the object 
        required: true
        schema:
          $ref: "#/definitions/CreatePet_Request"
    responses:
      200:
        description: OK

definitions:
  CreatePet_Request:
    type: object
    properties:
      requestVariant:
        type: string
    required:
    - requestVariant
    discriminator: requestVariant

  PetDescriptionObject:
    allOf:
    - $ref: "#/definitions/CreatePet_Request"
    - type: object
      properties: 
        name: 
          type: string
        description:
          type: string

  PetCatalogEntry:
    allOf:
    - $ref: "#/definitions/CreatePet_Request"
    - type: object
      properties: 
        SKU: 
          type: string
        Breed:
          type: string
        Comments:
          type: string

Ни один из этих методов не привязан к типу носителя запроса. Хотя ваш запрос может принимать несколько типов мультимедиа, если использование определенного типа мультимедиа подразумевает некоторые требования к телу запроса, вам придется задокументировать это в свойстве description операции или параметра тела.

person Ted Epstein    schedule 17.12.2016
comment
Вопрос касался requestBody, которого я нигде не вижу в вашем ответе. Я пришел сюда в поисках примера использования схемы $ ref в requestBody, так как я не могу понять, куда идет имя параметра в этом случае. Спецификация OpenAPI 3.0, похоже, тоже не показывает этого, например определение схемы PetBody. - person user9645; 10.01.2019