jsonyamlswaggerinternationalizationrails-i18n

How can I define a Map with arbitrary keys in a Swagger model


How can I define a map with arbitrary keys in a Swagger model

Say I have the following internationalised model (in Ruby-style pseudocode, assuming use of something like Globalize)

class Thingy
  translates :name
  attribute :code
end

and my API wishes to be able to return something like

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

but I don't want to restrict the range of translation keys in the actual API

I can define in my swagger doc

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

That validates but the Swagger Codegen won't generate anything off the additionalProperties and it's not very explicit compared to somehow being able to define a map type with a mix of required and arbitrary keys.

Anyone working with internationalisation is going to face similar issues so my question is, how have other people dealt with this scenario?


Solution

  • This works under swagger-codegen-2.1.1-M1 (Java/JavaJaxRS) ... with Ron's suggestions ...

    The YAML ...

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

    creates a Map with a 'default' attribute ...

    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;
        }
    
    }
    

    Which in turn is embedded in a 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;
        }
    
    }