LoginSignup
0
0

More than 1 year has passed since last update.

oapi-codegenでHash Map (additionalProperties) はどうexportされるか

Posted at

Go言語で Open API 3.0対応の型情報を生成するとき、
github.com/deepmap/oapi-codegen
を使ってます。

あまりユースケースとしてやりませんが、マップを表現したい時があると思います。
Dictionaries/HashMaps の仕様はこれです。
Dictionaries, HashMaps and Associative Arrays

oapi-codegenの公式のReadmeでは、additionalPropertiesに関しては一応対応していると書いてますが、
定義が実際にどう構造体として出力されるか見てみました。

定義

API定義

...
components:
  schemas:
...
    Sample:
      title: Sample
      type: object
      properties:
        id:
          type: integer
          format: int64
        related_image_asset_ids:
          type: array
          items:
            type: integer
        image_asset_id_to_url_map:
          type: object
          additionalProperties:
            type: string
          description: 'example : { "1" : "https://img.com/xxxx.png" }'
      required:
        - id
        - related_image_asset_ids
        - image_asset_id_to_url_map


出力


// Sample defines model for Sample.
type Sample struct {
    Id int64 `json:"id"`

    // example : { "1" : "https://img.com/xxxx.png" }
    ImageAssetIdToUrlMap Sample_ImageAssetIdToUrlMap `json:"image_asset_id_to_url_map"`
    RelatedImageAssetIds []int                       `json:"related_image_asset_ids"`
}

// example : { "1" : "https://img.com/xxxx.png" }
type Sample_ImageAssetIdToUrlMap struct {
    AdditionalProperties map[string]string `json:"-"`
}

...

// Getter for additional properties for Sample_ImageAssetIdToUrlMap. Returns the specified
// element and whether it was found
func (a Sample_ImageAssetIdToUrlMap) Get(fieldName string) (value string, found bool) {
    if a.AdditionalProperties != nil {
        value, found = a.AdditionalProperties[fieldName]
    }
    return
}

// Setter for additional properties for Sample_ImageAssetIdToUrlMap
func (a *Sample_ImageAssetIdToUrlMap) Set(fieldName string, value string) {
    if a.AdditionalProperties == nil {
        a.AdditionalProperties = make(map[string]string)
    }
    a.AdditionalProperties[fieldName] = value
}

// Override default JSON handling for Sample_ImageAssetIdToUrlMap to handle AdditionalProperties
func (a *Sample_ImageAssetIdToUrlMap) UnmarshalJSON(b []byte) error {
    object := make(map[string]json.RawMessage)
    err := json.Unmarshal(b, &object)
    if err != nil {
        return err
    }

    if len(object) != 0 {
        a.AdditionalProperties = make(map[string]string)
        for fieldName, fieldBuf := range object {
            var fieldVal string
            err := json.Unmarshal(fieldBuf, &fieldVal)
            if err != nil {
                return errors.Wrap(err, fmt.Sprintf("error unmarshaling field %s", fieldName))
            }
            a.AdditionalProperties[fieldName] = fieldVal
        }
    }
    return nil
}

// Override default JSON handling for Sample_ImageAssetIdToUrlMap to handle AdditionalProperties
func (a Sample_ImageAssetIdToUrlMap) MarshalJSON() ([]byte, error) {
    var err error
    object := make(map[string]json.RawMessage)

    for fieldName, field := range a.AdditionalProperties {
        object[fieldName], err = json.Marshal(field)
        if err != nil {
            return nil, errors.Wrap(err, fmt.Sprintf("error marshaling '%s'", fieldName))
        }
    }
    return json.Marshal(object)
}

additionalProperties:
  type: string

はセッター/ゲッター/変換レシーバ付きの専用Structとして出力されました。

構造体をvalueとしたいときは

additionalProperties:
  $ref: '#/components/schemas/Message'

こうしますが、こちらも同様の動作で map[string]Message が出力されました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0