Reputation: 2765
I am very new in Go and I was exploring go to use for one of my micro services. I was wonder the way Go converts objects to Json and back to Json. But unfortunately i found configuring the output field names are little difficult with the use of tag names.
type MyStruct strust{
MyName string
}
will converts to json
{
"MyName" : "somestring"
}
But we are following a naming strategy for the whole api across Organization to follow snake_case
{
"my_name" : "somestring"
}
Is considered to be valid in my org.
I started using the tags like json:"my_name,omitempty"
etc per field level.
I would like to know is there a way i can configure it at global project level, so that i dont want to take care this at every object and its field level.
Upvotes: 4
Views: 2695
Reputation: 4834
You could try something like this: https://play.golang.org/p/Vn-8XH_jLp5
Core functionality:
// SnakeCaseEncode snake_case's the given struct's field names.
func SnakeCaseEncode(i interface{}) map[string]interface{} {
rt, rv := reflect.TypeOf(i), reflect.ValueOf(i)
if rt.Kind() == reflect.Ptr {
i := reflect.Indirect(rv).Interface()
rt, rv = reflect.TypeOf(i), reflect.ValueOf(i)
}
out := make(map[string]interface{}, rt.NumField())
for i := 0; i < rt.NumField(); i++ {
if rt.Field(i).Tag.Get("json") == "-" {
continue
}
if strings.Contains(rt.Field(i).Tag.Get("json"), "omitempty") &&
rv.Field(i).IsZero() { // Go 1.13
continue
}
k := snakeCase(rt.Field(i).Name)
out[k] = rv.Field(i).Interface()
}
return out
}
// snakeCase provides basic ASCII conversion of camelCase field names to snake_case.
func snakeCase(s string) string {
out := make([]rune, 0, utf8.RuneCountInString(s))
for i, r := range s {
if r >= 'A' && r <= 'Z' {
r += 32
if i > 0 {
out = append(out, '_')
}
}
out = append(out, r)
}
return string(out)
}
To support map, slice etc. you'll have to expand on this simple version.
Upvotes: 3