在Golang中,如何将JSON中的snake_case键转换为camelCase的递归?
我在golang中写了一个http api。此api从数据存储区获取数据,进行一些计算并将响应作为JSON返回。
情况是数据存储区中的JSON文档(elasticsearch)存在snake_case键,而API响应应该基于camelCase(这只是为了与项目中的其他api标准一致)。插入ES的源无法修改。所以它只能在api级别进行密钥转换。
我编写了一个很好地从数据存储区读取JSON的结构。但是如何在golang中将密钥转换为camlelCase?
JSON可以嵌套,并且必须转换所有键。 JSON是任意大的。即一些键只是映射到类型interface {}
我也使用go的echo框架来编写api。
实施例
{
"is_modified" : true,
{ attribute":
{
"legacy_id" : 12345
}
}
}
要
{
"isModified" : true,
{ attribute":
{
"legacyId" : 12345
}
}
}
关于如何在golang中执行此操作的任何指示?
感谢。
STRUCT:
type data_in_es struct {
IsModified bool `json:"is_modified,omitempty"`
Attribute *attribute `json:"attribute,omitempty"`
}
type attribute struct {
LegacyId int `json:"legacy_id,omitempty"`
}
答案 0 :(得分:13)
从Go 1.8开始,你可以定义两个只在标签上有所不同的结构,并在两者之间进行简单的转换:
package main
import (
"encoding/json"
"fmt"
)
type ESModel struct {
AB string `json:"a_b"`
}
type APIModel struct {
AB string `json:"aB"`
}
func main() {
b := []byte(`{
"a_b": "c"
}`)
var x ESModel
json.Unmarshal(b, &x)
b, _ = json.MarshalIndent(APIModel(x), "", " ")
fmt.Println(string(b))
}
https://play.golang.org/p/dcBkkX9zQR
要执行此操作,请尝试将JSON文档解组为映射。如果成功,则修复所有键并递归调用函数以获取映射中的每个值。以下示例显示如何将所有键转换为大写。将fixKey
替换为snake_case转换函数。
package main
import (
"bytes"
"encoding/json"
"fmt"
"strings"
)
func main() {
// Document source as returned by Elasticsearch
b := json.RawMessage(`{
"a_b": "c",
"d_e": ["d"],
"e_f": {
"g_h": {
"i_j": "k",
"l_m": {}
}
}
}`)
x := convertKeys(b)
buf := &bytes.Buffer{}
json.Indent(buf, []byte(x), "", " ")
fmt.Println(buf.String())
}
func convertKeys(j json.RawMessage) json.RawMessage {
m := make(map[string]json.RawMessage)
if err := json.Unmarshal([]byte(j), &m); err != nil {
// Not a JSON object
return j
}
for k, v := range m {
fixed := fixKey(k)
delete(m, k)
m[fixed] = convertKeys(v)
}
b, err := json.Marshal(m)
if err != nil {
return j
}
return json.RawMessage(b)
}
func fixKey(key string) string {
return strings.ToUpper(key)
}