07 How to Understanding Cookie in Golang
Introduction to Cookies
Before discussing Cookies, we need to know that HTTP is stateless between client and server, which means the server does not store any data to remember every request from the client. This aims to make it easy to scale the server itself. So how do you get the server to remember a client? for example, when we have logged in to a website, the server must automatically know that the client has logged in so that subsequent requests no longer require logging in. For things like this, we can usually use Cookies.
Cookies are an HTTP feature which is provided by the server through a cookie response (key-value) and the client will store the cookie in the web browser. This way, when the client makes the next request, the client will always bring the cookie automatically. And the server will automatically always receive the cookie data brought by the client every time the client makes a request.
In Golang, we can use the http.SetCookie function to use cookies on the server so that later the client can automatically use cookies in its requests.
Implementation
Now we will try to understand it more deeply by providing an example like the code below.
1func SetCookieHandler(w http.ResponseWriter, r *http.Request) {
2 cookie := new(http.Cookie)
3 cookie.Name = "X-PXN-Name"
4 cookie.Value = r.URL.Query().Get("name")
5 cookie.Path = "/"
6 http.SetCookie(w, cookie)
7 fmt.Fprintf(w, "Success create cookie")
8}
9
10func GetCookieHandler(w http.ResponseWriter, r *http.Request) {
11 cookie, err := r.Cookie("X-PXN-Name")
12 if err != nil {
13 fmt.Fprint(w, "no cookie")
14 } else {
15 fmt.Fprintf(w, "hello %s", cookie.Value)
16 }
17}So that we can see in the browser whether the cookie has been set or not, we need to add more to the main.go file as below.
1func main() {
2 mux := http.NewServeMux()
3
4 mux.HandleFunc("/set-cookie", SetCookieHandler)
5 mux.HandleFunc("/get-cookie", GetCookieHandler)
6
7 server := http.Server{
8 Addr: "localhost:8080",
9 Handler: mux,
10 }
11
12 err := server.ListenAndServe()
13 if err != nil {
14 panic(err)
15 }
16}How to carry out tests or tests by running the program.
1go build && ./learn-golang-webThen we open the Chrome or Mozilla browser and do an inspect element. If it has been accessed using a browser it will look like the image below.

Then when we access another handler to get cookies at the URL http://localhost:8080/get-cookie, it will look like the image below.

We test the function above which will set a cookie on the endpoint handler so that we know that the cookie being set is as set in the function.
1func TestSetCookieHandler(t *testing.T) {
2 type args struct {
3 name string
4 }
5 tests := []struct {
6 name string
7 args args
8 want string
9 }{
10 {
11 name: "set cookie",
12 args: args{
13 name: "santekno",
14 },
15 want: "santekno",
16 },
17 }
18 for _, tt := range tests {
19 t.Run(tt.name, func(t *testing.T) {
20 request := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost/say?name=%s", tt.args.name), nil)
21 recorder := httptest.NewRecorder()
22 SetCookieHandler(recorder, request)
23
24 cookies := recorder.Result().Cookies()
25
26 for _, cookie := range cookies {
27 if !reflect.DeepEqual(cookie.Value, tt.want) {
28 t.Errorf("response = %s, want %s", cookie.Value, tt.want)
29 }
30 }
31
32 })
33 }
34}And we also do a unit test for the get cookie function below.
1func TestGetCookieHandler(t *testing.T) {
2 type args struct {
3 name string
4 }
5 tests := []struct {
6 name string
7 args args
8 want string
9 }{
10 {
11 name: "get cookie handler without cookie",
12 args: args{
13 name: "",
14 },
15 want: "no cookie",
16 },
17 {
18 name: "get cookie handler with cookie",
19 args: args{
20 name: "santekno",
21 },
22 want: "hello santekno",
23 },
24 }
25 for _, tt := range tests {
26 t.Run(tt.name, func(t *testing.T) {
27 request := httptest.NewRequest(http.MethodGet, "http://localhost/say", nil)
28 if tt.args.name != "" {
29 cookie := new(http.Cookie)
30 cookie.Name = "X-PXN-Name"
31 cookie.Value = tt.args.name
32 request.AddCookie(cookie)
33 }
34
35 recorder := httptest.NewRecorder()
36 GetCookieHandler(recorder, request)
37
38 response := recorder.Result()
39 body, _ := io.ReadAll(response.Body)
40 bodyString := string(body)
41
42 if !reflect.DeepEqual(bodyString, tt.want) {
43 t.Errorf("response = %s, want %s", bodyString, tt.want)
44 }
45 })
46 }
47}