programming

08 How To Use Streaming Decoder

Introduction to Stream Decoder

In the previous article, we studied the JSON package by using conversion of JSON data which was already in the form of variables and string data or we used []byte. Sometimes the JSON data comes from input in the form of io.Reader, which can be in the form of a file, network or request body. So we could just read all the data first, then store it in a variable and then convert it from JSON, but we don’t need to do this because the JSON package has a feature for reading data from Stream.

In the JSON package, if we want to create a JSON Decoder we just need to use the function

json.NewDecoder(reader)

Next, read the reader input and convert it directly by Golang using the function

json.Decode(interface)

Use of Stream Decoder

We can demonstrate the use of the JSON Decoder in the file below.

func DecodeStreamReaderJSON(file string) Customer {
	reader, _ := os.Open(file)
	decoder := json.NewDecoder(reader)

	var customer Customer
	err := decoder.Decode(&customer)
	if err != nil {
		panic(err)
	}
	return customer
}

Then we prepare the sample.json file with the data as below.

{
  "first_name": "Santekno",
  "middle_name": "Ihsan",
  "last_name": "Arif",
  "hobbies": [
    "badminton",
    "renang",
    "coding"
  ]
}

We can see in the ConvertStreamReaderJSON function that in the first line we read the file with the name sent by the parameter, so the file can be in different shapes, but in this case we take the data from the file in JSON form to make it easier.

Conceptually, this may be the same as converting data, but the difference is that the data is taken in ‘Stream’ form, where we need to read the contents of the file in the parameters sent. So this really makes it easier for us when, for example, we want to retrieve data in the form of a file or an API that sends JSON, then we don’t need to convert twice but we only need to convert once using json.Decode.

To test the function that we have created, we make sure to create a unit test like the one below.

func TestDecodeStreamReaderJSON(t *testing.T) {
	type args struct {
		file string
	}
	tests := []struct {
		name string
		args args
		want Customer
	}{
		{
			name: "success convert stream reader",
			args: args{
				file: "sample.json",
			},
			want: Customer{
				FirstName:  "Santekno",
				MiddleName: "Ihsan",
				LastName:   "Arif",
				Hobbies:    []string{"badminton", "renang", "coding"},
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := DecodeStreamReaderJSON(tt.args.file); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("DecodeStreamReaderJSON() = %v, want %v", got, tt.want)
			}
		})
	}
}
comments powered by Disqus