Mengurangi Load ke Backend dengan Cache-Control

Saat ini pemisahan service back end dan front end banyak digunakan dalam sebuah website. Salah satu alasannya adalah agar dapat scale up back end atau font end secara terpisah. Secara umum, resource yang diperlukan back end lebih besar dari pada yang diperlukan front end, sehingga diperlukan suatu cara untuk mengurangi load ke back end. Salah satu caranya adalah dengan caching. Untungnya ada header Cache-Control yang sangat membantu. Dengan header ini, back end dapat mengontrol bagaimana seharusnya front end meng-cache resource. Cache-Control pada umumnya digunakan untuk file gambar dan file statik seperti javascript. Header ini juga bisa digunakan untuk ajax JSON request atau request jenis apapun. Pada artikel ini akan dijelaskan bagaimana cara menggunakan Cache-Control untuk mengurangi load ke back end.

Apa itu Cache-Control

Cache-Control adalah HTTP header yang memberitahu client tentang aturan caching untuk suatu resource. Contoh value nya adalah max-age=3600. Ini berarti browser harus menggunakan cache untuk resource tersebut selama 3600 detik atau satu jam. Apabila ada request untuk resource yang sama dalam rentang waktu satu jam, browser tidak akan hit backe end, tetapi akan menggunakan response yang sudah di cache. Ini berarti tidak ada request yang masuk ke back end sehingga dapat mengurangi load.

P: Apa yang akan terjadi jika max-age sudah lewat?
J: Front end akan hit back end untuk mendapatkan response terbaru.

P: Kalau max-age sudah lewat tapi tetap tidak ada perubahan pada resource, bagaimana?
J: Front end bisa memverifikasi ke back end apakah ada perubahan pada resource tersebut. Kalau tidak ada, bisa menggunakan cache yang sebelumnya.

P: Bagaimana caranya?
J: Menggunakan header etag.

Etag adalah header HTTP yang menunjukkan semacam versi dari suatu resource. Ketika browser mendapat header etag di response, browser akan menggunakan value nya di header If-None-Match pada request selanjutnya. Back end akan mengecek apakah value dari If-None-Match sama dengan value etag terbaru dari resource yang diinginkan. Kalau versi back end dan front end sama, back end dapat meresponse dengan HTTP code 304 dengan response body kosong. Kalau front end mendapatkan code 304, cache sebelumnya akan digunakan. Hal ini juga dapat mengurangi load ke back end karena tidak perlu mengambil resource dari database.
Apabila ada update pada resource, back end harus mengupdate versi etag nya juga. Sehingga front end mendapatkan data yang terbaru.

Menggunakan Cache-Control untuk mengurangi

Service kita mungkin memiliki resource yang sering diupdate dan resource yang jarang diupdate. Cache-Control dapat digunakan untuk kedua case tersebut. Untuk resource yang jarang diupdate, kita dapat menggunakan max-age dengan expiry yang lama. Gunakan juga header etag untuk menandai versi nya.
Contoh menggunakan golang:

var menuVersion = 1
var cacheExpirySeconds = 3600

func HandleGetMenu(w http.ResponseWriter, r *http.Request) {
    if match := r.Header.Get("If-None-Match"); match != "" && match == menuVersion {
        w.WriteHeader(http.StatusNotModified) // http code: 304
        return
    }

    menu := fetchMenu() 

    w.Header().Set("Etag", fmt.Sprint(menuVersion))
    w.Header().Add("Cache-Control", fmt.Sprintf("max-age=%d", cacheExpirySeconds)
    w.Write(menu)
}

Pada contoh ini, saya menggunakan menuVersion yang di hardcode sebagai etag. Untuk aplikasi beneran, kita perlu menyimpan nilai nya ke suatu database. Baris 4-7 mengecek apakah menuVersion di server sama dengan yang dikirim oleh client. Kalau sama, server akan merespond dengan HTTP code 304 dan body kosong. Server tidak perlu memanggil fungsi fetch untuk mengambil resource.
Untuk resource yang sering diupdate, kita dapat menggunakan max-age=0 di header Cache-Control dengan versi nya di etag. Ini berarti client akan selalu hit back end, tapi kalau versi etag nya sama, server tinggal meresponse dengan code 304.

Kesimpulan

Menurut saya header Cache-Control dan etag sangat berguna karena dengan ini back end dapat mengontrol bagaimana client meng-cache response. Header ini di support oleh semua browser besar. Kalau digunakan dengan benar, load ke backend dapat berkurang secara signifikan. Tetapi kalo salah configurasi, kita mungkin perlu meminta user untuk clear cache di brower. Kalau punya pendapat atau ide lain, boleh kasih komen di bawah.


See also