Сложная модель ответа Swagger с динамическими хэш-картами значений ключей

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

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

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

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

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

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

3 ответа

Решение

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

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

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

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

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

Эта последняя проблема связана с недостатком проекта в Swagger-Model, одном из основных компонентов, используемых в стеке Swagger Java (включая 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 предполагается, что ключи хеш-таблицы являются строками, поэтому тип ключа не определен явно. additionalProperties определить тип значений hashmap. Итак, эта схема

type: object
additionalProperties: 
  type: string

определяет отображение строка-строка, например:

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

Если вам нужно преобразовать строку в целое, например:

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

вы бы определили additionalProperties как имеющий тип значения 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,

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

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

Схема модели в редакторе Swagger

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

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

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

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