programming

Get to know Package Context With Value in Golang

Introduction to the context.WithValue package

At the beginning of the context explanation, we know that the context will be created for the first time during initialization using context.Background() or context.TODO(), where the context does not have a value, aka it is still empty. We can add values from a context with a concept like a map, namely [key - value].

If we add a value to the context, it will automatically create a new child context and the initial context (original) will not be changed at all. And how to add the value, namely with the context.WithValue(parent, text) method.

Why should we use context?

context.WithValue is useful for storing information or data from the beginning when we create a process to the inside of the functions that we have defined so that until the last function we know what the value set in the initial function is like and has been passed to the function. -whichever function the context is running in.

Implementation and samples

Before going into the code, we need to first understand the diagram below.

context diagram

We will create a context by looking at the flow sequence in the diagram above. Making context A as a parent and having 2 child contexts, namely context B and context C. Then context B has more children, namely context D and E, but context C only has one child context, namely context F. So that you don’t get confused, let’s just try the code below.

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
}

The results of the program when we run it will appear as below

✗ 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>

Conclusion

context can carry values from the parent to the lowest child so that whatever is below that we can use in the child context in the next process so that we don’t need to send any more inappropriate params, so in the child function we will capture it directly through the context only .

comments powered by Disqus