pemrograman

07 Memahami Cookie

Sebelum ke pembahasan Cookie kita perlu ketahui bahwa HTTP merupakan stateless antara client dan server yang artinya server tidak menyimpan data apapun untuk mengingat setiap request dari client. Hal ini bertujuan agar mudah melakukan scalability dari server itu sendiri. Lalu bagaimana cara agar server bisa mengingat sebuah client? misalnya ketika kita sudah login di suatu website, secara otomatis server harus tahu jika client tersebut sudah login sehingga request selanjutnya tidak perlu lagi melakukan login. Hal seperti ini bisanya kita bisa memanfaatkan Cookie.

Cookie adalah fitur HTTP yang mana diberikan oleh server melalui response cookie (key-value) dan client akan menyimpan cookie tersebut di web browser. Dengan demikian, ketika client melakukan request selanjutnya, client akan selalu membawa cookie tersebut secara otomatis. Dan server secara otomatis akan selalu menerima data cookie tersebut yang dibawa oleh client setiap client melakukan request.

Pada Golang, kita bisa menggunakan function http.SetCookie untuk menggunakan cookie di server sehingga nanti dari client bisa secara otomatis menggunakan cookie pada request-nya.

Implementasi

Sekarang kita akan coba memahami lebih dalam dengan memberikan contoh seperti kode dibawah ini.

func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
	cookie := new(http.Cookie)
	cookie.Name = "X-PXN-Name"
	cookie.Value = r.URL.Query().Get("name")
	cookie.Path = "/"
	http.SetCookie(w, cookie)
	fmt.Fprintf(w, "Success create cookie")
}

func GetCookieHandler(w http.ResponseWriter, r *http.Request) {
	cookie, err := r.Cookie("X-PXN-Name")
	if err != nil {
		fmt.Fprint(w, "no cookie")
	} else {
		fmt.Fprintf(w, "hello %s", cookie.Value)
	}
}

Agar kita bisa melihat pada browser apakah Cookie tersebut sudah di set atau belum maka, kita perlu menambahkan lagi pada file main.go seperti dibawah ini.


func main() {
	mux := http.NewServeMux()

	mux.HandleFunc("/set-cookie", SetCookieHandler)
	mux.HandleFunc("/get-cookie", GetCookieHandler)

	server := http.Server{
		Addr:    "localhost:8080",
		Handler: mux,
	}

	err := server.ListenAndServe()
	if err != nil {
		panic(err)
	}
}

Cara melakukan pengujian atau test dengan menjalankan programnya.

go build && ./learn-golang-web

Lalu kita buka browser Chrome atau Mozilla dan lakukan inspect element. Jika sudah diakses menggunakan browser maka akan terlihat seperti gambar dibawah ini.

web set cookie

Lalu ketika kita mengakses handler satu lagi untuk mendapatkan cookie pada url http://localhost:8080/get-cookie, maka akan terlihat seperti gambar dibawah ini.

web get cookie

Kita uji fungsi diatas yang mana akan melakukan set cookie pada endpoint handler tersebut sehingga kita tahu bahwa cookie yang diset itu seperti yang sudah diset pada fungsi tersebut.

func TestSetCookieHandler(t *testing.T) {
	type args struct {
		name string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "set cookie",
			args: args{
				name: "santekno",
			},
			want: "santekno",
		},
	}
	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()
			SetCookieHandler(recorder, request)

			cookies := recorder.Result().Cookies()

			for _, cookie := range cookies {
				if !reflect.DeepEqual(cookie.Value, tt.want) {
					t.Errorf("response = %s, want %s", cookie.Value, tt.want)
				}
			}

		})
	}
}

Dan kita juga melakukan unit test untuk fungsi get cookie dibawah ini.

func TestGetCookieHandler(t *testing.T) {
	type args struct {
		name string
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "get cookie handler without cookie",
			args: args{
				name: "",
			},
			want: "no cookie",
		},
		{
			name: "get cookie handler with cookie",
			args: args{
				name: "santekno",
			},
			want: "hello santekno",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			request := httptest.NewRequest(http.MethodGet, "http://localhost/say", nil)
			if tt.args.name != "" {
				cookie := new(http.Cookie)
				cookie.Name = "X-PXN-Name"
				cookie.Value = tt.args.name
				request.AddCookie(cookie)
			}

			recorder := httptest.NewRecorder()
			GetCookieHandler(recorder, request)

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

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