我有一个像这样的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
}
}
}