Last active
July 31, 2024 21:43
-
-
Save bxcodec/c2a25cfc75f6b21a0492951706bc80b8 to your computer and use it in GitHub Desktop.
Golang Struct To Map Example By JSON tag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This function will help you to convert your object from struct to map[string]interface{} based on your JSON tag in your structs. | |
Example how to use posted in sample_test.go file. | |
*/ | |
func structToMap(item interface{}) map[string]interface{} { | |
res := map[string]interface{}{} | |
if item == nil { | |
return res | |
} | |
v := reflect.TypeOf(item) | |
reflectValue := reflect.ValueOf(item) | |
reflectValue = reflect.Indirect(reflectValue) | |
if v.Kind() == reflect.Ptr { | |
v = v.Elem() | |
} | |
for i := 0; i < v.NumField(); i++ { | |
tag := v.Field(i).Tag.Get("json") | |
field := reflectValue.Field(i).Interface() | |
if tag != "" && tag != "-" { | |
if v.Field(i).Type.Kind() == reflect.Struct { | |
res[tag] = structToMap(field) | |
} else { | |
res[tag] = field | |
} | |
} | |
} | |
return res | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sample_test | |
import ( | |
"encoding/json" | |
"fmt" | |
"testing" | |
"github.com/stretchr/testify/require" | |
) | |
type SampleStruct struct { | |
Name string `json:"name"` | |
ID string `json:"id"` | |
} | |
type EmbededStruct struct { | |
FieldStruct `json:"field"` | |
Hello string `json:"hello"` | |
} | |
type FieldStruct struct { | |
OnePoint string `json:"one_point"` | |
Sample *SampleStruct `json:"sample"` | |
} | |
func TestStructToMap_Normal(t *testing.T) { | |
sample := SampleStruct{ | |
Name: "John Doe", | |
ID: "12121", | |
} | |
res := structToMap(sample) | |
require.NotNil(t, res) | |
fmt.Printf("%+v \n", res) | |
// Output: map[name:John Doe id:12121] | |
jbyt, err := json.Marshal(res) | |
require.NoError(t, err) | |
fmt.Println(string(jbyt)) | |
// Output: {"id":"12121","name":"John Doe"} | |
} | |
func TestStructToMap_FieldStruct(t *testing.T) { | |
sample := &SampleStruct{ | |
Name: "John Doe", | |
ID: "12121", | |
} | |
field := FieldStruct{ | |
Sample: sample, | |
OnePoint: "yuhuhuu", | |
} | |
res := structToMap(field) | |
require.NotNil(t, res) | |
fmt.Printf("%+v \n", res) | |
// Output: map[sample:0xc4200f04a0 one_point:yuhuhuu] | |
jbyt, err := json.Marshal(res) | |
require.NoError(t, err) | |
fmt.Println(string(jbyt)) | |
// Output: {"one_point":"yuhuhuu","sample":{"name":"John Doe","id":"12121"}} | |
} | |
func TestStructToMap_EmbeddedStruct(t *testing.T) { | |
sample := &SampleStruct{ | |
Name: "John Doe", | |
ID: "12121", | |
} | |
field := FieldStruct{ | |
Sample: sample, | |
OnePoint: "yuhuhuu", | |
} | |
embed := EmbededStruct{ | |
FieldStruct: field, | |
Hello: "WORLD!!!!", | |
} | |
res := structToMap(embed) | |
require.NotNil(t, res) | |
fmt.Printf("%+v \n", res) | |
//Output: map[field:map[one_point:yuhuhuu sample:0xc420106420] hello:WORLD!!!!] | |
jbyt, err := json.Marshal(res) | |
require.NoError(t, err) | |
fmt.Println(string(jbyt)) | |
// Output: {"field":{"one_point":"yuhuhuu","sample":{"name":"John Doe","id":"12121"}},"hello":"WORLD!!!!"} | |
} |
The below worked for me
func structToMap(data interface{}) (map[string]interface{}, error) {
dataBytes, err := json.Marshal(data)
if err != nil {
return nil, err
}
mapData := make(map[string]interface{})
err = json.Unmarshal(dataBytes, &mapData)
if err != nil {
return nil, err
}
return mapData, nil
}
@ahmadissa I'm using the similar approach but I was wondering if we could directly convert struct
to map
without involving []byte
This will also fail, if the json tag includes "omitempty"
for example:
type User struct {
Uid string json:"uid,omitempty"
Name string json:"name,omitempty"
Email string json:"email,omitempty"
Mobile_no string json:"mobile_no,omitempty"
Shortlisted []ShortList json:"shortlisted,omitempty"
}
the resulted json key insuch case will be mobile_no,omitempty
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this will fail on more complex struct as below, mainly in the slice of struct part