Go – 实时修改 JSON

huangapple go评论74阅读模式
英文:

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:

&quot;object&quot;: {
  &quot;array&quot;: [
    {
      &quot;element_field_1&quot;: some_value_1,
      &quot;element_field_2&quot;: some_value_1,
      ... // More unknown fields
    },
    ...
  ],
  &quot;object_field&quot;: 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&#39;s body to an interface
	j := getDecodedJSON(r)

    // Iterate over every element of the array
	for i := 0; i &lt; len(j[&quot;object&quot;][&quot;array&quot;]); i++ {
		rewrite(j[&quot;object&quot;][&quot;array&quot;][i])
	}

    // Encoding back to JSON shouldn&#39;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(&amp;j); err != nil {
		log.Fatal(err)
	}
	return j
}

func rewrite(element *map[string]interface{}) {
	element[&quot;element_field_1&quot;], element[&quot;element_field_2&quot;] = lookupValues(element)
}

Basically the error is:

invalid operation: j[&quot;object&quot;][&quot;array&quot;] \
(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[&quot;object&quot;][&quot;array&quot;][i]

to

j[&quot;object&quot;].(map[string]interface{})[&quot;array&quot;].([]interface{})[i]

huangapple
  • 本文由 发表于 2015年5月28日 04:31:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/30492568.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定