Модель комплексного ответа Swagger c динамическими картами хэша значений ключей

Я борюсь с синтаксисом swagger для описания типа ответа. Я пытаюсь смоделировать хэш-карту с динамическими ключами и значениями. Это необходимо для локализации. Языки могут различаться, но английский всегда должен быть обеспечен.

ответ будет выглядеть так в JSON:

{
  id: "1234",
  name: {
    en: "english text",
    de: "Deutscher Text"
  }
}

моя первая попытка выглядела так, но я понятия не имею, как написать часть для имени. AdditionalProperties кажется ключом, но я не могу обернуть голову вокруг него. Также требование к английскому тексту является для меня загадкой в этом синтаксисе, и пример также не работает, как ожидалось. Он генерирует пустой $folded: в пользовательском интерфейсе.

delayReason:
  type: object
  properties:
    id:
      type: string
      description: Identifier for a delay reason.
    name:
      type: object
      additionalProperties: 
        type: string
  required: [id, name]
  example:
    id: 123
    name: 
      en: english text
      de: Deutscher Text

но это производит: swagger editor result

в этом также нет подсказки, что результат будет иметь код языка в качестве ключа и текст в качестве значения хэш-карты.

3 ответов


похоже, вы столкнулись по крайней мере с тремя отдельными ошибками и/или ограничениями:

  1. ни Swagger-Editor, ни Swagger-UI не предоставляют никаких указаний в формате документации, чтобы показать, что additionalProperties разрешены в схеме объекта. Так что даже там, где вы использовали additionalProperties правильно, и он распознается анализатором Swagger, эти форматы документации не будут показывать его. Вам нужно добавить эту деталь в схемы description, Так что пользователи понимают, что они могут включить дополнительные строковые свойства.

    Примечание: вероятно, вы также ожидаете, что дополнительные имена свойств будут соответствовать соглашению, например, двухбуквенному коду языка. При полном схемы JSON можно указать с patternProperties, к сожалению, это не поддерживается в объекте схемы Swagger. Опять же, вы должны указать это в своем описании схемы.

  2. формат Swagger-Editor иногда показывает это странное свойство" folded:". Я видел это утро, теперь, как ни странно, я не могу воспроизвести его. Возможно, сегодня все было подстроено. Но независимо от этого, это, безусловно, ошибка, и специфичная для Swagger-Editor. Это не должно влиять на генерацию нисходящего кода или стандартный Swagger-UI, который представляет документацию API разработчикам клиентов во время выполнения. (Хотя панель документации в Swagger-Editor похожа на Swagger-UI, это отдельная реализация.)

  3. есть некоторые тонкие, но значительные ограничения на использование additionalProperties в развязность. В то время как Хеленпример не показывает никаких видимых ошибок, на самом деле парсер Swagger не сможет правильно обработать эту схему; он будет игнорировать либо ваш явно объявленный en свойства, или будет игнорировать additionalProperties!

эта последняя проблема сводится к недостатку дизайна в Swagger-Model, одном из основных компонентов, используемых во всем стеке Java Swagger (включая Swagger-Codegen). Схемы, определенные в некоторые контексты могут работать с комбинацией properties и additionalProperties. Но схемы, определенные в других контекстах, не могут.

мы подробно задокументировано здесь.

хорошая новость: с небольшой настройкой мы можем заставить пример Хелен работать правильно. Нам просто нужно извлечь вложенную схему объекта в собственное определение верхнего уровня. Я назову это LocalizedName:

definitions:
  delayReason:
    type: object
    properties:
      id:
        type: string
        description: Identifier for a delay reason.
      name:
        $ref: "#/definitions/LocalizedName"
    required: [id, name]
    example:
      id: '123' # Note the quotes to force the value as a string
      name: 
        en: English text
        de: Deutscher Text

  LocalizedName:
    type: object
    description: A hashmap with language code as a key and the text as the value.
    properties:
      en:
        type: string
        description: English text of a delay reason.
    required: [en]
    additionalProperties: 
      type: string

использование additionalProperties правильно, и ваша модель правильная.

additionalProperties

в Swagger/OpenAPI ключи hashmap считаются строками, поэтому тип ключа не определяется явно. additionalProperties определите тип значений hashmap. Итак, эта схема

type: object
additionalProperties: 
  type: string

определяет строковую карту, такую как:

{
  "en": "English text",
  "de": "Deutscher Text"
}

Если вам нужна карта строка-целое число, например:

{
  "en": 5,
  "de": 3
}

определить additionalProperties as имея тип значения integer:

type: object
additionalProperties: 
  type: integer

необходимый ключ в hashmap

определение en в качестве необходимого ключа в hashmap:

type: object
properties:
  en:
    type: string
required: [en]
additionalProperties: 
  type: string

пример

definitions:
  delayReason:
    type: object
    properties:
      id:
        type: string
        description: Identifier for a delay reason.
      name:
        type: object
        description: A hashmap with language code as a key and the text as the value.
        properties:
          en:
            type: string
            description: English text of a delay reason.
        required: [en]
        additionalProperties: 
          type: string
    required: [id, name]
    example:
      id: '123' # Note the quotes to force the value as a string
      name: 
        en: English text
        de: Deutscher Text

в этом также нет подсказки, что результат будет иметь код языка в качестве ключа и текст в качестве значения хэш-карты.

такие вещи могут быть описаны словесно в description.

в пример также не работает, как ожидалось. Он генерирует пустой $folded: в пользовательском интерфейсе.

не уверен, что проблема была с вашей оригинальной спецификацией, но спецификация выше действительна и отлично выглядит в Редактор Swagger.

Model schema in Swagger Editor


Если вы все еще находитесь на стадии разработки, вместо использования динамических ключей вы можете нажать все ссылки на другие языки в массиве со структурой, такой как:

{
"launguage":"en"
"text":"Hello World"
}

Это значительно упростило бы ситуацию, и поскольку вы не полагаетесь на additionalProperties, ваши сгенерированные клиентские библиотеки найдут это более легким для усвоения.