如何在Swagger模型中定义一个具有任意键的Map

8

如何在Swagger模型中定义具有任意键的map

假设我有以下国际化模型(使用类似Globalize的东西的Ruby风格伪代码):

class Thingy
  translates :name
  attribute :code
end

我的API希望能够返回类似于以下的内容:

{
  "thingy": {
    "code": "barn", 
    "translations": {
      "default": "barn", 
      "en": "barn", 
      "ru": "cарай", 
      "fr": "grange", 
      "nl": "schuur"
    }
  }
}

但我不想在实际的API中限制翻译键的范围。

我可以在我的Swagger文档中定义。

definitions:
  thingy:
    required:
      - code
    properties:
      code:
        type: string
    additionalProperties:
      translations:
        required:
          - default
        property:
          default:
            type: string
        additonalProperties: string

这个验证通过了,但Swagger Codegen不会生成任何有关additionalProperties的内容,而且与定义一个混合了必需和任意键的map类型相比,它并不是很明确。

任何从事国际化工作的人都会面临类似的问题,所以我的问题是,其他人是如何处理这种情况的?

2个回答

9

这可以在swagger-codegen-2.1.1-M1(Java/JavaJaxRS)中使用...随着Ron的建议...

YAML ...

translation:
  required:
    - default
  properties:
    default:
      type: string
  additionalProperties:
    type: string

thingy:
  required:
    - code
  properties:
    code:
      type: string
    translations:
      $ref: '#/definitions/translation'

创建一个带有“默认”属性的Map...
public class Translation extends HashMap<String, String> {

    /**
     * 
     */
    @Expose
    private String _default = null;

    /**
     * @return  _default the _default
     */
    public String getDefault() {
        return _default;
    }

    /**
     * @param  _default to set
     */
    public void setDefault(String _default) {
        this._default = _default;
    }

}

这反过来嵌入在一个Thingy中......

public class Thingy  {

    /**
     * 
     */
    @Expose
    private String code = null;

    /**
     * 
     */
    @Expose
    private Translation translations = null;

    /**
     * @return  code the code
     */
    public String getCode() {
        return code;
    }

    /**
     * @param  code to set
     */
    public void setCode(String code) {
        this.code = code;
    }

    /**
     * @return  translations the Translations
     */
    public Translation getTranslations() {
        return translations;
    }

    /**
     * @param  translations the Translations to set
     */
    public void setTranslations(Translation translations) {
        this.translations = translations;
    }

}

这正是我最终得到的结果 - 感谢 Ron 和你的帮助。 - Dave Sag

2

虽然上述定义在理论上是有效的,但它并不能翻译出你想要描述的内容,也不受Swagger的支持。

为了描述你想要的结构,你需要以下定义:

thingy:
  type: object
  required:
    - code
  properties:
    code:
      type: string
    translations:
      type: object
      required:
          - default
      properties:
          default:
            type: string
      additonalProperties: 
          type: string

虽然你可以像上面那样内联定义内部对象,但我强烈建议你将定义外部化,并使用$reftranslations定义中引用它。

至于代码生成器,最近已经引入了对映射的支持,所以应该可以工作。如果您发现它不起作用,请直接在包含Swagger定义的项目上打开一个问题,以帮助调试。


谢谢Ron,这很有帮助。我考虑了你的建议并进行了扩展 - 请参见https://gist.github.com/davesag/c8cf393f1a14d4df757e - Dave Sag
在那儿加了一个注释。 - Ron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接