pemrograman

03 Penggunaan Query Parameter

Pengenalan Query Parameter

Query parameter adalah salah satu fitur dari http yang biasanya kita gunakan untuk mengirim data dari client ke dalam server. Query pameter ini ditempatkan pada URL dari endpoint yang sudah kita buat. Untuk menambahkan query parameter, kita bisa gunakan ?=nama=value pada URL website kita.

Package url.URL

Package yang kita pakai untuk mengenal parameter query yaitu url.URL pada parameter request. Dari URL ini kita bisa mengambil data query parameter yang dikirim dari client dengan menggunakan method Query() dengan pengembalian data tipe map.

Contohnya kita akan membuat handler yang menerima parameter dari client seperti dibawah ini.

func SayHelloParameterHandler(w http.ResponseWriter, r *http.Request) {
	name := r.URL.Query().Get("name")
	if name == "" {
		fmt.Fprint(w, "Hello")
	} else {
		fmt.Fprintf(w, "Hello %s", name)
	}
}

Fungsi ini perlu kita buktikan hasil ini berjalan dengan baik, kita perlu menambahkan unit test seperti dibawah ini.

func TestSayHelloParameterHandler(t *testing.T) {
	type args struct {
		name string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "success return response with name",
			args: args{
				name: "santekno",
			},
			want: "Hello santekno",
		},
		{
			name: "success return response without name",
			args: args{
				name: "",
			},
			want: "Hello",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost/say?name=%s", tt.args.name), nil)
			recorder := httptest.NewRecorder()
			SayHelloParameterHandler(recorder, request)

			response := recorder.Result()
			body, _ := io.ReadAll(response.Body)
			bodyString := string(body)

			if !reflect.DeepEqual(bodyString, tt.want) {
				t.Errorf("response = %v, want %v", bodyString, tt.want)
			}
		})
	}
}

Multiple Query Parameter

Ketika kita ingin menerima lebih dari satu parameter yang dikirim oleh client maka spesifikasi URL ini sudah bisa mendukung untuk mengirim banyak parameter ke dalam server dengan cara kita bisa gunakan tanda & lalu diikuti dengan query parameter berikutnya.

Contohnya pada client dikirim dua parameter query dan nantinya akan diterima oleh server dengan handler dibawah ini.

func MultipleParameterHandler(w http.ResponseWriter, r *http.Request) {
	firstName := r.URL.Query().Get("first_name")
	lastName := r.URL.Query().Get("last_name")
	if firstName == "" && lastName == "" {
		fmt.Fprint(w, "Hello")
	} else {
		fmt.Fprintf(w, "Hello %s %s", firstName, lastName)
	}
}

kita coba test hasil dari fungsi yang sudah kita buat diatas dengan membuat unit test dibawah ini.

func TestMultipleParameterHandler(t *testing.T) {
	type args struct {
		firstName string
		lastName  string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "success return response with name",
			args: args{
				firstName: "Santekno",
				lastName:  "Inc",
			},
			want: "Hello Santekno Inc",
		},
		{
			name: "success return response without name",
			args: args{
				firstName: "",
				lastName:  "",
			},
			want: "Hello",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost/say?first_name=%s&last_name=%s", tt.args.firstName, tt.args.lastName), nil)
			recorder := httptest.NewRecorder()
			MultipleParameterHandler(recorder, request)

			response := recorder.Result()
			body, _ := io.ReadAll(response.Body)
			bodyString := string(body)

			if !reflect.DeepEqual(bodyString, tt.want) {
				t.Errorf("response = %v, want %v", bodyString, tt.want)
			}
		})
	}
}

Multiple Value Query Parameter

Query URL sebenarnya bisa kita melakukan parsing query parameter dan menyimpannya dalam tipe map[string][]string. Artinya, dalam satu key query parameter kita bisa memasukkan beberapa value. Bagaimana caranya? dengan cara menambahkan name parameter dengan nama yang sama namun value-nya berbeda-beda, misalkan:

name=Santekno&name=Ihsan

Sebelumnya kita menggunakan method Get() untuk mendapatkan datanya, karena saat ini kondisinya multiple value maka kita tidak bisa menggunakan method tersebut. Maka, ada cara lain agar data tersebut bisa kita ambil.

func MultipleParameterValueHandler(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	names := query["name"]
	if len(names) == 0 {
		fmt.Fprint(w, "Hello")
	} else {
		fmt.Fprintf(w, "Hello %s", strings.Join(names, " "))
	}
}

Kita coba lakukan test dengan membuat unit test agar bisa memastikan data sesuai dengan param yg dikirim.

func TestMultipleParameterValueHandler(t *testing.T) {
	type args struct {
		name []string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "success return response with name",
			args: args{
				name: []string{"santekno", "ihsan"},
			},
			want: "Hello santekno ihsan",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost/say?name=%s&name=%s", tt.args.name[0], tt.args.name[1]), nil)
			recorder := httptest.NewRecorder()
			MultipleParameterValueHandler(recorder, request)

			response := recorder.Result()
			body, _ := io.ReadAll(response.Body)
			bodyString := string(body)

			if !reflect.DeepEqual(bodyString, tt.want) {
				t.Errorf("response = %v, want %v", bodyString, tt.want)
			}
		})
	}
}
comments powered by Disqus