将json中的所有snake_case键转换为golang中的camelCase键

bad*_*tya 3 api json go

在Golang中,我们如何将JSON中的snake_case密钥转换为camelCase密钥?

我在golang写了一个http api.此api从数据存储区获取数据,进行一些计算并将响应作为JSON返回.

情况是数据存储区(elasticsearch)中的JSON文档与snake_case键一起出现,而API响应应该是基于camelCase的(这只是为了与项目中的其他api标准一致).插入ES的源无法修改.所以它只能在api级别进行密钥转换.

我编写了一个结构,可以很好地从数据存储区读取JSON.但是如何在golang中将密钥转换为camlelCase?

JSON可以嵌套,并且必须转换所有键.JSON是任意大的.即一些键只是映射到类型接口{}

我也使用go的echo框架来编写api.

防爆.

{
"is_modified" : true,
   { attribute": 
     {
      "legacy_id" : 12345 
     }
   }
}
Run Code Online (Sandbox Code Playgroud)

{
"isModified" : true,
   { attribute": 
     {
      "legacyId" : 12345 
     }
   }
}
Run Code Online (Sandbox Code Playgroud)

有关如何在golang中执行此操作的任何指示?

谢谢.

结构:

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"`
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*ter 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))
}
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/QQZPMGKrlg