英文:
Generate OpenAPI XML model from Go structure
问题
有没有办法使用golang结构生成一个OpenAPI规范文档(针对XML)?我的结构体使用了encoding/xml注解,像这样:
type Error struct {
Text string `xml:",chardata"`
Type string `xml:"Type,attr"`
Code string `xml:"Code,attr"`
ShortText string `xml:"ShortText,attr"`
}
我想自动生成一个符合这些注解的OpenAPI模型。
英文:
Is there any way to generate a OpenAPI specification document for XML using golang structure? My structures are annotated with encoding/xml annotations like this:
type Error struct {
Text string `xml:",chardata"`
Type string `xml:"Type,attr"`
Code string `xml:"Code,attr"`
ShortText string `xml:"ShortText,attr"`
}
I would like to generate a OpenAPI model automatically, which respect these annotations
答案1
得分: 2
你可以使用标准库中的reflect
包来检查结构体及其标签,可以使用gopkg.in/yaml.v3
包来生成Open API格式。你只需要编写逻辑,将你的类型转换为与Open API文档结构相匹配的类型。
以下是一个示例,注意这只是一个不完整的示例,因此不能直接使用:
// 声明一个与OpenAPI的yaml文档匹配的结构体
type DataType struct {
Type string `yaml:"type,omitempty"`
Props map[string]*DataType `yaml:"properties,omitempty"`
XML *XML `yaml:"xml,omitempty"`
}
type XML struct {
Name string `yaml:"name,omitempty"`
Attr bool `yaml:"attribute,omitempty"`
}
// 编写一个marshal函数,将给定的类型转换为上面声明的结构体
// - 此示例仅转换普通结构体
func marshalOpenAPI(v interface{}) (interface{}, error) {
rt := reflect.TypeOf(v)
if rt.Kind() == reflect.Struct {
obj := DataType{Type: "object"}
for i := 0; i < rt.NumField(); i++ {
f := rt.Field(i)
tag := strings.Split(f.Tag.Get("xml"), ",")
if len(tag) == 0 || len(tag[0]) == 0 { // 没有名称?
continue
}
if obj.Props == nil {
obj.Props = make(map[string]*DataType)
}
name := tag[0]
obj.Props[name] = &DataType{
Type: goTypeToOpenAPIType(f.Type),
}
if len(tag) > 1 && tag[1] == "attr" {
obj.Props[name].XML = &XML{Attr: true}
}
}
return obj, nil
}
return nil, fmt.Errorf("不支持的类型")
}
// 让所有的类型实现yaml.Marshaler接口
// 委托给上面实现的marshal函数
func (e Error) MarshalYAML() (interface{}, error) {
return marshalOpenAPI(e)
}
// 将类型进行编组
yaml.Marshal(map[string]map[string]interface{}{
"schemas": {
"error": Error{},
// ...
},
})
在playground上试一试。
英文:
You can use the reflect
package from the standard library to inspect the struct and its tags and you can use the gopkg.in/yaml.v3
package to generate the Open API format. You just need to write the logic that translates your type into another, one that matches the structure of the Open API document.
Here's an example of how you could approach this, note that it is incomplete and should therefore not be used as is:
// declare a structure that matches the OpenAPI's yaml document
type DataType struct {
Type string `yaml:"type,omitempty"`
Props map[string]*DataType `yaml:"properties,omitempty"`
XML *XML `yaml:"xml,omitempty"`
}
type XML struct {
Name string `yaml:"name,omitempty"`
Attr bool `yaml:"attribute,omitempty"`
}
// write a marshal func that converts a given type to the structure declared above
// - this example converts only plain structs
func marshalOpenAPI(v interface{}) (interface{}, error) {
rt := reflect.TypeOf(v)
if rt.Kind() == reflect.Struct {
obj := DataType{Type: "object"}
for i := 0; i < rt.NumField(); i++ {
f := rt.Field(i)
tag := strings.Split(f.Tag.Get("xml"), ",")
if len(tag) == 0 || len(tag[0]) == 0 { // no name?
continue
}
if obj.Props == nil {
obj.Props = make(map[string]*DataType)
}
name := tag[0]
obj.Props[name] = &DataType{
Type: goTypeToOpenAPIType(f.Type),
}
if len(tag) > 1 && tag[1] == "attr" {
obj.Props[name].XML = &XML{Attr: true}
}
}
return obj, nil
}
return nil, fmt.Errorf("unsupported type")
}
// have all your types implement the yaml.Marshaler interface by
// delegating to the marshal func implemented above
func (e Error) MarshalYAML() (interface{}, error) {
return marshalOpenAPI(e)
}
// marshal the types
yaml.Marshal(map[string]map[string]interface{}{
"schemas": {
"error": Error{},
// ...
},
})
Try it on playground.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论