英文:
Go - Modify JSON on the fly
问题
考虑到以下输入:
"object": {
"array": [
{
"element_field_1": some_value_1,
"element_field_2": some_value_1,
... // 更多未知字段
},
...
],
"object_field": foo,
... // 更多未知字段
}
我需要遍历数组的每个元素,修改字段1和字段2,然后输出JSON对象。以下是我目前的代码,但它远远不是有效的Go代码:
func handler(w http.ResponseWriter, r *http.Request) {
// 将请求的body转换为一个接口
j := getDecodedJSON(r)
// 遍历数组的每个元素
for i := 0; i < len(j["object"]["array"]); i++ {
rewrite(j["object"]["array"][i])
}
// 编码回JSON不应该是个问题
}
func getDecodedJSON(r *http.Request) map[string]interface{} {
dec := json.NewDecoder(r.Body)
var j map[string]interface{}
if err := dec.Decode(&j); err != nil {
log.Fatal(err)
}
return j
}
func rewrite(element *map[string]interface{}) {
element["element_field_1"], element["element_field_2"] = lookupValues(element)
}
基本上错误是:
invalid operation: j["object"]["array"] \
(type interface {} does not support indexing)
但当然我的方法还存在更多概念上的错误。
编写一个详细描述输入内容的struct
并不是一个真正的选项,因为我事先不知道JSON的键。
我应该如何以"Go的方式"解决这个问题?
编辑:这是实际的用例:
- 我有两个需要一个"翻译器"的Web服务。
- 服务1向翻译器发出请求,其中修改了一些字段,其他所有内容保持不变。
- 然后翻译器获取修改后的JSON并将请求复制到服务2。
换句话说,这个翻译器就像两个服务之间的中间人。鉴于Go的快速启动时间和快速的JSON处理能力,Go似乎是一个不错的选择。
我认为在Go的结构体中详细说明每个JSON字段并没有意义,因为我只需要更改一些字段。我愿意在效率上做出一些妥协(因为使用map[string]interface{}
进行解析应该比使用完整的结构体更慢),以换取使代码更通用于JSON输入的变化。
英文:
Considering the following input:
"object": {
"array": [
{
"element_field_1": some_value_1,
"element_field_2": some_value_1,
... // More unknown fields
},
...
],
"object_field": foo,
... // Some more unknown fields
}
I need to iterate over every element of the array, modify fields 1 and 2 and then output the JSON object. Here's what I have for now, but it is far from being valid Go code:
func handler(w http.ResponseWriter, r *http.Request) {
// Transform the request's body to an interface
j := getDecodedJSON(r)
// Iterate over every element of the array
for i := 0; i < len(j["object"]["array"]); i++ {
rewrite(j["object"]["array"][i])
}
// Encoding back to JSON shouldn't be a problem
}
func getDecodedJSON(r *http.Request) map[string]interface{} {
dec := json.NewDecoder(r.Body)
var j map[string]interface{}
if err := dec.Decode(&j); err != nil {
log.Fatal(err)
}
return j
}
func rewrite(element *map[string]interface{}) {
element["element_field_1"], element["element_field_2"] = lookupValues(element)
}
Basically the error is:
invalid operation: j["object"]["array"] \
(type interface {} does not support indexing)
but of course there's a more conceptual mistake on my approach.
Writing a struct
that details the content of the input isn't really an option, since I don't know the JSON keys beforehand.
How can I do this "the Go way"?
EDIT: This is the actual use case:
- I have two web services that need a "translator" between them.
- Service 1 makes a request to the translator, where a couple of fields are modified, everything else is left intact.
- Then the translator takes the modified JSON and replicates the request to service 2.
In other words, this translator acts like a man in the middle for both services. Go seems to be a good option for this given its fast startup times and fast JSON handling.
I don't think it makes sense to detail every JSON field in a Go struct, since I only need to change a few fields. I'm willing to make a tradeoff in efficiency because of reflection (parsing to a map[string]interface{}
should be slower than using a full-blown struct), in exchange of making the code more generic to variations of the JSON input.
答案1
得分: 3
将
j["object"]["array"][i]
改为
j["object"].(map[string]interface{})["array"].([]interface{})[i]
英文:
Change
j["object"]["array"][i]
to
j["object"].(map[string]interface{})["array"].([]interface{})[i]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论