从API解析结构

时间:2018-04-19 04:43:08

标签: json go

我试图通过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下的数据。

3 个答案:

答案 0 :(得分:1)

如果您要通过http://testapi.com/getdata/Ahttp://testapi.com/getdata/B访问API来使用API​​,则可以将AB视为驱动API的参数您的API的行为。

如果您传递A,您基本上想要访问与A相关联的网站数据,如果您传递B,则B的网站数据应该返回{1}}。

在内部组织此数据的一种简单方法是使用保留siteLob的专用转到类型URL,并通过map[string]site将所有内容排列在地图中在服务器启动时初始化。

然后,您可以动态访问为API提供的参数(AB,但可以轻松扩展),从地图中查找网站信息,如果是' 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中缺少的值将使用零值进行解组。 int0string""map,任何指针为nil。结构将被初始化,但它们的字段将具有零值。

在你的情况下,当json中缺少comcast时,B将被初始化为结构,其中Lob""URL是一个空的字符串片段。

答案 2 :(得分:0)

如果我理解正确,您有一个结构SiteList,并且根据用户是否导航到/getData/A/getData/B您想要投放SiteList.ASiteList.B

从json marshal docs here或this SO answer中,当结构为空时,可以省略结构的某些字段。基本上,如果该字段中没有数据,那么它将不会出现在编组的json中。

  

" omitempty" option指定应省略该字段   如果字段具有空值,则编码,定义为false,0,a   nil指针,一个nil接口值,以及任何空数组,切片,map,   或字符串。

考虑到这一点,如果您在请求的处理程序中拥有控件,以便能够根据路径在SiteList中设置值,那么您可以使用此功能。

如果将AB的共享部分提取到结构中:

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为空,因此不会被编组。)