Golang OpenAPI 3.0 oneOf构造

时间:2018-08-23 11:50:57

标签: go openapi

在Golang中是否存在一种更清洁的方法来实现围绕oneOf,anyOf,allOf的OpenAPI 3.0构造。我觉得拥有一个带有辨别器字段的扁平结构将是明智的。 (下面的示例)

package main

import (
    "encoding/json"
    "fmt"    
)

type OneOfCertification struct {
    AssetType   string           `json:"assetType"`
    CertDetails *json.RawMessage `json:"certDetails"`
}

type FlatCertification struct {
    AssetType   string   `json:"assetType"`
    DiamondCert *Diamond `json:"diamondCert,omitempty"`
    GemCert     *Gem     `json:"gemCert,omitempty"`
}

type Diamond struct {
    DiamondAttr string `json:"diamondAttr"`
}
type Gem struct {
    GemAttr string `json:"gemAttr"`
}

func oneOfUnmarshalMarshal(data []byte) ([]byte, error) {

    var cert OneOfCertification
    json.Unmarshal(data, &cert)
    switch cert.AssetType {
    case "DIA":
        var dia Diamond
        json.Unmarshal(*cert.CertDetails, &dia)
        fmt.Println("(oneOf) Diamond Cert Details:", dia)

        // Now lets try to Marshal concrete back to raw message
        b, _ := json.Marshal(&dia)
        certDtls := json.RawMessage(b)
        cert.CertDetails = &certDtls
    case "GEM":
        var gem Gem
        json.Unmarshal(*cert.CertDetails, &gem)
        fmt.Println("(oneOf) Gem Cert Details:", gem)

        // Now lets try to Marshal concrete back to raw message
        b, _ := json.Marshal(&gem)
        certDtls := json.RawMessage(b)
        cert.CertDetails = &certDtls

    }

    // Finally Marshal cert and send it back
    return json.Marshal(&cert)
}

func flatUnmarshal(data []byte) ([]byte, error) {
    var cert FlatCertification
    json.Unmarshal(data, &cert)
    switch cert.AssetType {
    case "DIA":
        fmt.Println("(flat) Gem Cert Details:", *cert.DiamondCert)
    case "GEM":
        fmt.Println("(flat) Gem Cert Details:", *cert.GemCert)
    }
    return json.Marshal(&cert)

}

func main() {
    oneOfDiaCert := `{"assetType":"DIA","certDetails":{"diamondAttr":"certified diamond"}}`
    oneOfGemCert := `{"assetType":"GEM","certDetails":{"gemAttr":"certified gem"}}`

    db, _ := oneOfUnmarshalMarshal([]byte(oneOfDiaCert))
    gb, _ := oneOfUnmarshalMarshal([]byte(oneOfGemCert))

    fmt.Println("(oneOf) marshalled diamond certification", string(db))
    fmt.Println("(oneOf) marshalled gem certification", string(gb))

    flatDiaCert := `{"assetType":"DIA","diamondCert":{"diamondAttr":"certified diamond"}}`
    flatGemCert := `{"assetType":"GEM","gemCert":{"gemAttr":"certified gem"}}`

    db, _ = flatUnmarshal([]byte(flatDiaCert))
    gb, _ = flatUnmarshal([]byte(flatGemCert))

    fmt.Println("(flat) marshalled diamond certification", string(db))
    fmt.Println("(flat) marshalled gem certification", string(gb))
}

使用json.RawMessage或任何接口{}编写的用于编组和解组的大量代码使它看起来很难看。在Golang中以更智能的方式实现它的任何想法??

0 个答案:

没有答案