programming

04 How to know Decode JSON

Introduction to JSON Decoding

In the previous article we learned to encode JSON and how to create a JSON object, so next we will learn how to translate JSON objects into struct objects in Golang. We often call this conversion from JSON into a Golang struct object as decode.

In Golang, to do this conversion or also known as decode we will use a function.

json.Unmarshal(byte[],interface{})

The function above has 2 parameters, namely

  • byte[] is the data from JSON to be converted
  • interface{} is a place to store the results of the conversion in the form of struct pointers that we create in Golang.

How to Implement

Have you started to imagine, friends? OK, we will try to create a function that can convert data from JSON objects into struct objects in Golang. Here, friends, try creating the function below.

func ConvertObjectJSON(data string) Customer {
	var cust Customer
	err := json.Unmarshal([]byte(data), &cust)
	if err != nil {
		panic(err)
	}

	return cust
}

Look at the function above, it will be seen that because the data is of type string we need to convert it first into bytes using []byte(data), then we will store the results of the conversion in a struct that has been initialized in the variable cust.

Because must the pointer be sent? Unmarshal will convert the JSON byte data and send the value into a pointer variable so that there are no nil variables. So the required pointer of a variable will allocate memory for non-nil storage. In the documentation explanation it is like this.

Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.

And the way the unmarshal works is like this

To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. By default, object keys which don't have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).

Next, we will test the function above by creating a unit test as below.

func TestConvertObjectJSON(t *testing.T) {
	type args struct {
		data string
	}
	tests := []struct {
		name string
		args args
		want Customer
	}{
		{
			name: "success conversion object JSON",
			args: args{
				data: string(`{"first_name":"Santekno","middle_name":"Ihsan","last_name":"Arif"}`),
			},
			want: Customer{
				FirstName:  "Santekno",
				MiddleName: "Ihsan",
				LastName:   "Arif",
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := ConvertObjectJSON(tt.args.data); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("ConvertObjectJSON() = %v, want %v", got, tt.want)
			}
		})
	}
}
comments powered by Disqus