In HTTP server each request is served by a handler function running in its own goroutine.

We often want to have common per-requested information available in a convenient way.

For example, at the beginning of handling a request we might check a cookie to see if a request is made by a logged in user and we want to have user info available everywhere.

We can do that by using context with value:

https://codeeval.dev/gist/a3641974265b2ec6d9aafb6332345798

For clarity of the example we only show creating a context with value and retrieving value from context.

Because context value is an interface{}, it’s a good practice to write type-safe wrapper functions for setting and retrieving values.

The key used to set / get value is also an interface{}. Because context can be passed to functions in code you didn’t write, you want to ensure that the value used for key is unique.

That’s why we defined a non-exported type userKeyType and used a non-exported global variable userKey of that type.

This ensures that code outside of our package can’t possibly use this key.

This wouldn’t be true if the key was e.g. a string (or any type available to multiple packages).

We wrote two functions for retrieving the value.

One panics when value is not set, another one returns nil.

Which one to use is a policy decision for your code.

Sometimes missing a variable on context means a bug in your program and you should use mustGetUserFromContext variant which panics in that case.

Sometimes missing a variable is expected and you can use getUserFromContext variant.