我试图通过Go访问存储在json文件中的一些信息。我有两个相关的问题。一个是我不确定如何组织我的结构,其次是如何通过变量访问它们。我会记下我的代码以使其更有意义
// To be clear, this is dummy info and I'm linting my actual json
// data. It loads fine, I just don't want to get hung up on this side
{
"A": {
"lob": "A",
"url": [
"example.com",
"test.com"]
}
"B": {
"lob": "B",
"url": [
"example2.com",
"test2.com"]
}
}
所以关注的是选项的结构是相同的。我正在构建它作为REST AP的一部分。希望用户可以使用http://testapi.com/getdata/A,它将返回A下的URL和名称信息,同样也返回B.同样,它将它们作为同一结构的独立组件加载:
type SiteList struct {
A struct {
Lob string `json:"lob"`
URL []string `json:"url"`
} `json:"test"`
B struct {
Lob string `json:"lob"`
URL []string `json:"url"`
} `json:"test2"`
}
我可以手动执行.A或.B但我想知道如何在请求进入时处理它,以便我的API只返回A或B下的数据。
答案 0 :(得分:1)
如果您要通过http://testapi.com/getdata/A或http://testapi.com/getdata/B访问API来使用API,则可以将A
和B
视为驱动API的参数您的API的行为。
如果您传递A
,您基本上想要访问与A
相关联的网站数据,如果您传递B
,则B
的网站数据应该返回{1}}。
在内部组织此数据的一种简单方法是使用保留site
和Lob
的专用转到类型URL
,并通过map[string]site
将所有内容排列在地图中在服务器启动时初始化。
然后,您可以动态访问为API提供的参数(A
或B
,但可以轻松扩展),从地图中查找网站信息,如果是' sa有效的网站,返回编码为JSON的相应数据。
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type site struct {
Lob string `json:"lob"`
URL []string `json:"url"`
}
var sites = map[string]site{
"A": site{
Lob: "A",
URL: []string{
"example.com",
"test.com",
},
},
"B": site{
Lob: "B",
URL: []string{
"example2.com",
"test2.com",
},
},
}
const endpoint = "/getdata/"
func handler(w http.ResponseWriter, r *http.Request) {
lob := r.URL.Path[len(endpoint):]
s, ok := sites[lob]
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
resp, err := json.Marshal(s)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Write(resp)
}
func main() {
http.HandleFunc(endpoint, handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
答案 1 :(得分:0)
json中缺少的值将使用零值进行解组。 int
为0
,string
为""
,map
,任何指针为nil
。结构将被初始化,但它们的字段将具有零值。
在你的情况下,当json中缺少comcast时,B将被初始化为结构,其中Lob
是""
而URL
是一个空的字符串片段。
答案 2 :(得分:0)
如果我理解正确,您有一个结构SiteList
,并且根据用户是否导航到/getData/A
或/getData/B
您想要投放SiteList.A
或SiteList.B
从json marshal docs here或this SO answer中,当结构为空时,可以省略结构的某些字段。基本上,如果该字段中没有数据,那么它将不会出现在编组的json中。
" omitempty" option指定应省略该字段 如果字段具有空值,则编码,定义为false,0,a nil指针,一个nil接口值,以及任何空数组,切片,map, 或字符串。
考虑到这一点,如果您在请求的处理程序中拥有控件,以便能够根据路径在SiteList
中设置值,那么您可以使用此功能。
如果将A
和B
的共享部分提取到结构中:
type Inner struct {
Lob string `json:"lob"`
URL []string `json:"url"`
}
// using pointers here for A and B means setting to nil is empty
type SiteList struct {
A *Inner `json:"test,omitempty"`
B *Inner `json:"test2,omitempty"`
}
然后将您不希望在响应正文中的那个设置为nil。 (对于指针,nil为空,因此不会被编组。)