从api调用中提取json信息,以便在go中进行比较



我有一个像这样的JSON文件,我用它来更新服务器上的信息:

{
"environments": [
{
"environment": "dev",
"features": [
{ "name": "newa", "enable": true },
{ "name": "newb", "enable": true }
]
}
]
}

查询API以从服务器获取信息,返回如下JSON信息。我通过一个名为apicall((的函数获得这些信息

{
"name": "Default",
"environments": [
"dev",
"prod"
],
"features": [
{
"type": "release",
"name": "newa",
"createdAt": "2022-01-01T11:01:53.054Z",
"lastSeenAt": null,
"stale": false,
"environments": [
{
"name": "dev",
"enabled": true,
"type": "dev",
"sortOrder": 100
},
{
"name": "prod",
"enabled": false,
"type": "prod",
"sortOrder": 200
}
]
},
{
"type": "release",
"name": "newb",
"createdAt": "2022-01-01T11:01:53.087Z",
"lastSeenAt": null,
"stale": false,
"environments": [
{
"name": "dev",
"enabled": true,
"type": "dev",
"sortOrder": 100
},
{
"name": "prod",
"enabled": false,
"type": "prod",
"sortOrder": 200
}
]
}
],
"members": 1,
"version": 1
}

每次我更新JSON文件(例如删除、创建和更新功能信息(时,新信息都应该通过API调用在服务器中进行属性更新。

要删除、创建和更新服务器中的功能信息,我已经有了一个函数调用apiupdate((。基本上,我可以从JSON文件中更新/创建/删除的是功能名称environment.features.name和启用/禁用它environment.features.启用

每次更新文件时,都会触发一个功能,将新信息更新到服务器中。因此,我必须将当前的JSON文件与从服务器提取的信息进行比较,以进行适当的更改。

到目前为止,我所尝试的只是在json文件中不存在的情况下创建功能名称:

func triggered(token string, filejson string) {
data := FeatureVars(filejson)
for _, env := range data.Environments {
for _, feature := range env.Features {
url := "xxxx"
response := statusfeature(url, token)
fmt.Printf("response:%s", response)
if response != "200 OK" {
// Calling apiupdate()
apiupdate(url_base, token, feature.Name)
}
}
}
}

其中状态自然是:

func statusfeature(url string, token string) string {
// Setup the request
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", token)
// Executing request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err.Error()
}
// Close response body as required
defer resp.Body.Close()
r := fmt.Sprintf("%d %s", resp.StatusCode, http.StatusText(resp.StatusCode))
fmt.Printf("response:%s", r)
return r
}

例如,如果我从原始JSON文件中删除了功能名称newa,现在我需要比较通过JSON中的函数apicall((从服务器中提取的信息,并通过函数apiupdate((TR从服务器中删除此功能名称

问题是,我很难将JSON中从服务器提取的信息与用于更新服务器当前信息的JSON文件进行比较。这里有必要使用json吗。取消对((进行比较

如何将现有的JSON文件与JSON中从服务器提取的信息进行比较,以做出相应的更改?我想在修改原始JSON文件时在一个新函数中进行比较,以便更新服务器的信息。

我可以用golang中的任何文档/示例吗?

我仍然不完全确定你在寻找什么,但这里有一个关于如何解析json数据并逐步完成它的草图:

您可以将数据解析为嵌套的map[string]interface{},它更紧凑,但在有许多字段的情况下使用起来会很麻烦——您必须一直进行类型转换。

或者,您可以声明表示json数据结构的结构类型(至少是必需字段(。您可以使用以下工具https://mholt.github.io/json-to-go/以避免手工作业。

package main
import (
"encoding/json"
"time"
)
type APIConfig struct {
Environments []struct {
Environment string `json:"environment"`
Features    []struct {
Name   string `json:"name"`
Enable bool   `json:"enable"`
} `json:"features"`
} `json:"environments"`
}
type StatusFeature struct {
Name         string   `json:"name"`
Environments []string `json:"environments"`
Features     []struct {
Type         string      `json:"type"`
Name         string      `json:"name"`
CreatedAt    time.Time   `json:"createdAt"`
LastSeenAt   interface{} `json:"lastSeenAt"`
Stale        bool        `json:"stale"`
Environments []struct {
Name      string `json:"name"`
Enabled   bool   `json:"enabled"`
Type      string `json:"type"`
SortOrder int    `json:"sortOrder"`
} `json:"environments"`
} `json:"features"`
Members int `json:"members"`
Version int `json:"version"`
}
func main() {
fromConfigString := `{environments": [{"environment": "dev",---"...` // truncated for readability, your config
var apiConfig APIConfig // we create an empty instance of APIConfig
err := json.Unmarshal([]byte(fromConfigString), &apiConfig) // since you example seems to use strings, we need to convert them to byte slices
if err != nil {
panic(err)
}
statusFeatureString := `{"name":"Default","environments": ["dev","prod" ], ...` // truncated for readability, your server response
var statusFeature StatusFeature // we create an empty instance of StatusFeature
err = json.Unmarshal([]byte(statusFeatureString), &statusFeature)
if err != nil {
panic(err)
}
for _, fCE2 := range apiConfig.Environments {
var found bool
// it's probably nicer to extract the nested search loops into a separate method and just return true or false,
// but I keep it here for the sake of compactness
search:
for _, fCF := range fCE2.Features {
for _, fS := range statusFeature.Features {
if fS.Name == fCF.Name {
found = true
break search
}
}
}
if found {
// the feature from the config was found in the response. Do your stuff
}
}
}

最新更新