在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中以更智能的方式实现它的任何想法??