Swagger complex response model with dynamic key value hash maps

后端 未结 3 877
滥情空心
滥情空心 2020-12-14 08:17

I\'m struggling with the syntax of swagger to describe a response type. What I\'m trying to model is a hash map with dynamic keys and values. This is needed to allow a local

相关标签:
3条回答
  • 2020-12-14 08:53

    Your usage of additionalProperties is correct and your model is correct.

    additionalProperties

    In Swagger/OpenAPI, hashmap keys are assumed to be strings, so the key type is not defined explicitly. additionalProperties define the type of hashmap values. So, this schema

    type: object
    additionalProperties: 
      type: string
    

    defines a string-to-string map such as:

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

    If you needed a string-to-integer map such as:

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

    you would define additionalProperties as having value type integer:

    type: object
    additionalProperties: 
      type: integer
    

    Required key in a hashmap

    To define en as a required key in the hashmap:

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

    Complete example

    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
    

    There is also no clue in this that the result will have a language code as a key and the text as the value of the hash map.

    Things like that can be documented verbally in the description.

    the example also does not seem to work as expected. It generates an empty $folded: in the UI.

    Not sure what the problem was with your original spec, but the spec above is valid and looks fine in the Swagger Editor.

    Model schema in Swagger Editor

    0 讨论(0)
  • 2020-12-14 09:04

    If you're still in the design stage, instead of using dynamic keys, you can push all the other language references in an array with structure like:

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

    That would simplify things a lot, and since you're not relying on additionalProperties, your generated client libraries will find this easier to digest.

    0 讨论(0)
  • 2020-12-14 09:14

    It seems you are running into at least three separate bugs and/or limitations:

    1. Neither Swagger-Editor nor Swagger-UI provide any indication in the documentation format to show that additionalProperties are allowed in your object schema. So even where you've used additionalProperties correctly, and it's recognized by the Swagger parser, these documentation formats won't show it. You need to add this detail to your schema description, so users understand that they can include additional string properties.

      Note: You probably also expect the additional property names to follow a convention, e.g. a two-letter language code. While full JSON Schema lets you specify this with patternProperties, unfortunately that's not supported in Swagger's schema object. So again, you should specify that in your schema description.

    2. The Swagger-Editor format sometimes shows this odd "folded:" property. I saw it this morning, now strangely I cannot reproduce it. It might have been hotfixed today. But regardless, it's certainly a bug, and specific to Swagger-Editor. It should not affect your downstream code generation, nor the standard Swagger-UI that presents your API documentation to client developers at runtime. (Though the documentation pane in Swagger-Editor looks similar to Swagger-UI, it is a separate implementation.)

    3. There are some subtle but significant limitations to the use of additionalProperties in Swagger. While Helen's example doesn't show any visible errors, in fact the Swagger parser will fail to process this schema correctly; it will ignore either your explicitly declared en property, or will ignore additionalProperties!

    This last issue comes down to a design flaw in Swagger-Model, one of the core components used throughout the Swagger Java stack (including Swagger-Codegen). Schemas defined in certain contexts can work with a combination of properties and additionalProperties. But schemas defined in other contexts cannot.

    We've documented this in detail here.

    The good news: with a small tweak, we can make Helen's example work correctly. We just need to extract the nested object schema into its own top-level definition. I'll call it 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
    
    0 讨论(0)
提交回复
热议问题