go - Golang OpenAPI 3.0 oneOf 构造
问题描述
有没有一种更简洁的方法可以在 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 中以更智能的方式实现它的任何想法?