Golang中结构体对象列表的JSON Schema实现
Golang中结构体对象列表的JSON Schema实现 今天开始接触Go语言…总的来说我很喜欢它,但还有一些概念我正在努力理解,比如如何创建一个包含元组的结构体…我有以下想要响应的JSON模式。
[
{
"cmd": "string",
"service": "string",
"src": "string",
"dest": "string",
"weight": float,
"tags": ["string"],
"opts": {"string":"string"}
}
]
并且我有以下代码
type consulService struct {
Cmd string `json:"cmd"`
Service string `json:"service"`
Src string `json:"src"`
Dest string `json:"dest"`
Weight float32 `json:"weight"`
Tags []string `json:"tags"`
Opts []string `json:"opts"`
}
func getConsulServices(w http.ResponseWriter, req *http.Request) {
consultServiceCatalg := []consulService{
{
Cmd: "test",
Service: "CustomService",
Src: "/",
Dest: "http://1.1.1.1:5555/",
Weight: 100,
Tags: []string{"custom","service"},
Opts: {"k1" :"s1", "k2": "s2", "Kn":"etc"},
},
}
fmt.Println(consultServiceCatalg)
js, err := json.Marshal(consultServiceCatalg)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(js)
}
我的问题是Opts变量…我如何在类型对象中表示一个字符串列表…我是否需要创建一个新的类型Opts…其键值对类型为字符串…简而言之就是一个元组,但我没能在Golang中找到这种类型…
这里最大的问题是键是动态的而不是静态的。
这对于有超过一天Go语言经验的人来说可能显而易见。谢谢。
更多关于Golang中结构体对象列表的JSON Schema实现的实战教程也可以访问 https://www.itying.com/category-94-b0.html
map[string]string
更多关于Golang中结构体对象列表的JSON Schema实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
感谢为我指明了正确的方向。
我学习了关于映射的知识。
type consulService struct {
Cmd string `json:"cmd"`
Service string `json:"service"`
Src string `json:"src"`
Dst string `json:"dst"`
Weight float32 `json:"weight"`
Tags []string `json:"tags"`
Opts map[string]string `json:"opts"`
}
func getConsulServices(w http.ResponseWriter, req *http.Request) {
consultServiceCatalg := []consulService{
{
Cmd: "route add",
Service: "CustomService",
Src: "/home",
Dst: "http://1.1.1.1",
Weight: 100,
Tags: []string{"custom"},
Opts: map[string]string{"strip": "/path", "proto": "tcp"},
},
}
在Go语言中,处理动态键值对(键是字符串,值也是字符串)的正确方式是使用map[string]string类型。你的Opts字段应该定义为这种类型,而不是[]string。
以下是修正后的代码:
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type consulService struct {
Cmd string `json:"cmd"`
Service string `json:"service"`
Src string `json:"src"`
Dest string `json:"dest"`
Weight float32 `json:"weight"`
Tags []string `json:"tags"`
Opts map[string]string `json:"opts"` // 使用map而不是slice
}
func getConsulServices(w http.ResponseWriter, req *http.Request) {
consulServiceCatalog := []consulService{
{
Cmd: "test",
Service: "CustomService",
Src: "/",
Dest: "http://1.1.1.1:5555/",
Weight: 100,
Tags: []string{"custom", "service"},
Opts: map[string]string{ // 正确初始化map
"k1": "s1",
"k2": "s2",
"Kn": "etc",
},
},
}
fmt.Printf("结构体数据: %+v\n", consulServiceCatalog)
js, err := json.MarshalIndent(consulServiceCatalog, "", " ")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(js)
}
func main() {
// 测试JSON序列化
testData := []consulService{
{
Cmd: "test",
Service: "CustomService",
Src: "/",
Dest: "http://1.1.1.1:5555/",
Weight: 100,
Tags: []string{"custom", "service"},
Opts: map[string]string{
"k1": "s1",
"k2": "s2",
"Kn": "etc",
},
},
}
jsonData, _ := json.MarshalIndent(testData, "", " ")
fmt.Println("生成的JSON:")
fmt.Println(string(jsonData))
}
输出结果:
[
{
"cmd": "test",
"service": "CustomService",
"src": "/",
"dest": "http://1.1.1.1:5555/",
"weight": 100,
"tags": [
"custom",
"service"
],
"opts": {
"k1": "s1",
"k2": "s2",
"Kn": "etc"
}
}
]
如果需要处理更复杂的值类型(不仅仅是字符串),可以使用map[string]interface{}:
type consulService struct {
Cmd string `json:"cmd"`
Service string `json:"service"`
Src string `json:"src"`
Dest string `json:"dest"`
Weight float32 `json:"weight"`
Tags []string `json:"tags"`
Opts map[string]interface{} `json:"opts"` // 支持多种类型的值
}
// 使用示例
service := consulService{
Cmd: "test",
Service: "CustomService",
Src: "/",
Dest: "http://1.1.1.1:5555/",
Weight: 100,
Tags: []string{"custom", "service"},
Opts: map[string]interface{}{
"timeout": 30, // int
"enabled": true, // bool
"name": "test", // string
"tags": []string{"a", "b", "c"}, // slice
},
}
对于JSON Schema验证,可以使用第三方库如github.com/xeipuuv/gojsonschema:
import "github.com/xeipuuv/gojsonschema"
func validateJSONSchema(data []byte) error {
schemaLoader := gojsonschema.NewStringLoader(`{
"type": "array",
"items": {
"type": "object",
"properties": {
"cmd": {"type": "string"},
"service": {"type": "string"},
"src": {"type": "string"},
"dest": {"type": "string"},
"weight": {"type": "number"},
"tags": {"type": "array", "items": {"type": "string"}},
"opts": {"type": "object", "additionalProperties": {"type": "string"}}
},
"required": ["cmd", "service", "src", "dest", "weight", "tags", "opts"]
}
}`)
documentLoader := gojsonschema.NewBytesLoader(data)
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
if err != nil {
return err
}
if !result.Valid() {
return fmt.Errorf("JSON验证失败: %v", result.Errors())
}
return nil
}

