pemrograman

09 Cara Membuat Request Response Header Menggunakan Httprouter

Dalam pengembangan aplikasi berbasis web, pengaturan header pada HTTP request dan response sangat penting untuk mengelola data, keamanan, dan metadata lainnya. Artikel ini membahas langkah-langkah untuk mengatur header pada request dan response menggunakan library httprouter di Golang. Dengan panduan ini, bahkan programmer pemula dapat memahami konsep ini dengan mudah.

Prasyarat

Sebelum kita mulai, pastikan Anda memiliki hal-hal berikut:

  1. Instalasi Golang: Pastikan Go sudah terinstal di sistem Anda.
  2. Proyek Baru: Buat proyek baru dengan struktur file dasar.
  3. Library Httprouter: Pasang library httprouter dengan perintah berikut:
    go get github.com/julienschmidt/httprouter
    

Langkah 1: Mengatur Struktur Proyek

Buat struktur proyek berikut:

project/
├── main.go
└── handlers/
    └── headers.go

Langkah 2: Mengatur Header pada Response

Header pada response dikirim ke klien melalui objek http.ResponseWriter. Mari tambahkan handler untuk mengatur header response.

1. Membuat File Handlers

Buka file handlers/headers.go dan tambahkan kode berikut:

package handlers

import (
	"net/http"
	"github.com/julienschmidt/httprouter"
)

// ResponseHeaderHandler menambahkan header ke response
func ResponseHeaderHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("X-Custom-Header", "Belajar Golang")
	w.WriteHeader(http.StatusOK)
	w.Write([]byte(`{"message":"Header berhasil disetel!"}`))
}

2. Menghubungkan Handler di main.go

Buka file main.go dan tambahkan handler baru:

package main

import (
	"log"
	"net/http"
	"github.com/julienschmidt/httprouter"
	"project/handlers"
)

func main() {
	router := httprouter.New()

	// Menambahkan handler untuk response header
	router.GET("/set-response-header", handlers.ResponseHeaderHandler)

	log.Println("Server berjalan di http://localhost:8080")
	log.Fatal(http.ListenAndServe(":8080", router))
}

3. Menguji Endpoint

Jalankan server:

go run main.go

Akses endpoint di browser atau gunakan curl:

curl -i http://localhost:8080/set-response-header

Respons akan menunjukkan header yang telah ditambahkan.


Langkah 3: Mengatur Header pada Request

Untuk memanipulasi header pada request, kita dapat menggunakan objek http.Request. Di sini kita membuat middleware yang membaca dan memproses header request.

1. Menambahkan Middleware

Buka kembali file handlers/headers.go dan tambahkan fungsi berikut:

// RequestHeaderHandler memproses header dari request
func RequestHeaderHandler(next httprouter.Handle) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		headerValue := r.Header.Get("X-Requested-By")
		if headerValue == "" {
			http.Error(w, "X-Requested-By header missing", http.StatusBadRequest)
			return
		}

		next(w, r, ps)
	}
}

2. Menambahkan Handler Middleware

Modifikasi file main.go untuk menggunakan middleware:

router.GET("/validate-request-header", handlers.RequestHeaderHandler(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	w.Write([]byte("Header valid!"))
}))

3. Menguji Endpoint

Jalankan server kembali dan gunakan curl:

curl -i -H "X-Requested-By: ClientApp" http://localhost:8080/validate-request-header

Jika header valid, responsnya:

Header valid!

Jika header tidak ada, respons akan menunjukkan kesalahan:

X-Requested-By header missing

Langkah 4: Menambahkan Unit Test

Untuk memastikan bahwa fungsi-fungsi yang telah kita buat berjalan dengan benar, kita akan menambahkan unit test untuk kedua handler tersebut: ResponseHeaderHandler dan RequestHeaderHandler.

Berikut adalah contoh unit test yang dapat Anda gunakan.

1. Unit Test untuk ResponseHeaderHandler

Fungsi ResponseHeaderHandler bertugas untuk menambahkan header ke response dan mengirimkan status HTTP 200 beserta body JSON. Kita akan membuat unit test untuk memverifikasi apakah header dan status code telah disetel dengan benar.

Buat file handlers/headers_test.go dengan konten berikut:

package handlers

import (
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestResponseHeaderHandler(t *testing.T) {
	type args struct {
		image string
	}
	tests := []struct {
		name              string
		args              args
		wantHTTPStatus    int
		wantContentType   string
		wantXCustomHeader string
		wantResponse      string
	}{
		{
			name: "test get image",
			args: args{
				image: "photo.jpg",
			},
			wantHTTPStatus:    200,
			wantContentType:   "application/json",
			wantXCustomHeader: "Belajar Golang",
			wantResponse:      `{"message":"Header berhasil disetel!"}`,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			request := httptest.NewRequest(http.MethodGet, "http:localhost:8080/set-response-header", nil)
			recorder := httptest.NewRecorder()
			ResponseHeaderHandler(recorder, request, httprouter.Params{})

			// Cek apakah status code yang dihasilkan adalah 200 OK
			if status := recorder.Code; status != tt.wantHTTPStatus {
				t.Errorf("Response code is %v, want %v", status, tt.wantHTTPStatus)
			}

			// Cek apakah header Content-Type yang dihasilkan adalah 'application/json'
			if contentType := recorder.Header().Get("Content-Type"); contentType != tt.wantContentType {
				t.Errorf("Content-Type header is %v, want %v", contentType, tt.wantContentType)
			}

			// Cek apakah header X-Custom-Header yang dihasilkan sesuai
			if customHeader := recorder.Header().Get("X-Custom-Header"); customHeader != tt.wantXCustomHeader {
				t.Errorf("X-Custom-Header is %v, want %v", customHeader, tt.wantXCustomHeader)
			}

			// Cek apakah body response berisi pesan yang diinginkan
			if recorder.Body.String() != tt.wantResponse {
				t.Errorf("Body is %v, want %v", recorder.Body.String(), tt.wantResponse)
			}
		})
	}
}

2. Unit Test untuk RequestHeaderHandler

Fungsi RequestHeaderHandler adalah middleware yang memeriksa apakah header X-Requested-By ada pada request. Jika tidak ada, middleware ini akan mengembalikan status 400 dengan pesan kesalahan. Berikut adalah unit test untuk middleware ini:

Buat file handlers/headers_test.go dengan konten berikut:

package handlers

import (
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestRequestHeaderHandler(t *testing.T) {
	type args struct {
		XRequestBy string
	}
	tests := []struct {
		name         string
		args         args
		wantResponse string
		wantStatus   int
	}{
		{
			name: "valid request header",
			args: args{
				XRequestBy: "ClientApp",
			},
			wantResponse: "header valid",
			wantStatus:   http.StatusOK,
		},
		{
			name: "invalid request header",
			args: args{
				XRequestBy: "",
			},
			wantResponse: fmt.Sprintln("X-Requested-By header missing"),
			wantStatus:   http.StatusBadRequest,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Buat request dengan header yang valid
			req, err := http.NewRequest("GET", "/validate-request-header", nil)
			if err != nil {
				t.Fatal(err)
			}
			req.Header.Set("X-Requested-By", tt.args.XRequestBy)

			// Buat ResponseRecorder untuk menangkap response
			rr := httptest.NewRecorder()

			// Panggil middleware dan handler
			handler := RequestHeaderHandler(ValidHeader)
			handler(rr, req, httprouter.Params{})

			// Cek apakah status code yang dihasilkan adalah 400 Bad Request
			if status := rr.Code; status != tt.wantStatus {
				t.Errorf("Response code is %v, want %v", status, tt.wantStatus)
			}

			// Cek apakah body response sesuai
			if rr.Body.String() != tt.wantResponse {
				t.Errorf("Body is %s, want %s", rr.Body.String(), tt.wantResponse)
			}
		})
	}
}

func ValidHeader(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	w.Write([]byte("header valid"))
}

Kesimpulan

Dengan httprouter, Anda dapat dengan mudah meng

atur header pada HTTP request dan response. Mengatur header penting untuk komunikasi antara klien dan server, termasuk memastikan keamanan, kontrol caching, dan metadata.

Untuk pembaca yang ingin memperdalam, Anda dapat menjelajahi konsep seperti middleware chaining untuk mengelola lebih banyak alur logika secara modular. Selain itu, pertimbangkan menggunakan tools debugging seperti Postman atau Insomnia untuk menguji header secara visual, atau tambahkan logging ke middleware Anda untuk melacak header saat pengembangan.

Semoga panduan ini membantu Anda lebih memahami pengelolaan header dalam pengembangan aplikasi web di Golang. Jika ada pertanyaan, jangan ragu untuk berdiskusi!

comments powered by Disqus