Pengenalan package context.WithValue
Pada awal penjelasan context kita tahu bahwa context akan dibuat pertama kali saat inisialisasi dengan menggunakan context.Background()
atau context.TODO()
yang mana pada context tersebut tidak memiliki value alias masih kosongan. Kita bisa menambahkan value dari sebuah context dengan konsep seperti map yaitu [key - value].
Jika kita menambahkan value ke dalam context maka otomatis akan membuat child context baru dan context awal (original) tidak akan diubah sama sekali. Dan bagaimana cara menambahkan value tersebut yaitu dengan method context.WithValue(parent, text)
.
Kenapa kita harus menggunakan context?
context.WithValue
ini bermanfaat untuk menyimpan informasi atau data dari awal kita membuat suatu proses sampai ke bagian dalam fungsi-fungsi yang sudah kita definisikan sehingga sampai fungsi terakhir kita tahu value yang diset di fungsi awal isinya seperti apa saja dan sudah melewati ke fungsi-fungsi mana saja context tersebut berjalan.
Implementasi dan sampel
Sebelum ke dalam kode kita perlu pahami dulu diagram dibawah ini.
Kita akan membuat context dengan melihat urutan flow pada diagram diatas. Pembuatan context A sebagai parent dan memiliki 2 context child yaitu context B dan context C. Lalu context B memiliki child lagi yaitu context D dan E tetapi context C hanya memiliki satu context child yaitu context F. Agar tidak pusing langsung saja kita coba kodenya dibawah ini.
func main() {
contextA := context.Background()
contextB := context.WithValue(contextA, "b", "context B")
contextC := context.WithValue(contextA, "c", "context C")
contextD := context.WithValue(contextB, "d", "context D")
contextE := context.WithValue(contextB, "e", "context E")
contextF := context.WithValue(contextC, "f", "context F")
fmt.Println(contextA)
fmt.Println(contextB)
fmt.Println(contextC)
fmt.Println(contextD)
fmt.Println(contextE)
fmt.Println(contextF)
fmt.Println(contextF.Value("f")) // dapat
fmt.Println(contextB.Value("c")) // dapat
fmt.Println(contextF.Value("c")) // dapat dari parent
fmt.Println(contextF.Value("b")) // tidak dapat
fmt.Println(contextB.Value("D")) // tidak dapat mengambil value child
}
Hasil program ketika kita jalankan akan mengeluarkan seperti dibawah ini
✗ go run app.go
context.Background
context.Background.WithValue(type string, val context B)
context.Background.WithValue(type string, val context C)
context.Background.WithValue(type string, val context B).WithValue(type string, val context D)
context.Background.WithValue(type string, val context B).WithValue(type string, val context E)
context.Background.WithValue(type string, val context C).WithValue(type string, val context F)
context F
<nil>
context C
<nil>
<nil>
Kesimpulan
context
bisa membawa value dari parent sampai ke child yang paling bawah sehingga apapun yang dibawah itu bisa kita gunakan pada context child dalam proses berikutnya sehingga kita tidak perlu mengirimkan lagi param yang tidak sesuai, maka pada fungsi child akan kita tangkap langsung melalui context saja.