Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fix "should not use basic type string as key in context.WithValue" golint

Tags:

go

golint

I am passing an uuid in using the Context and WithValue to subsequent functions that handle this *http.request. This uuid is was passed in the authorization header to a REST call to identify a person. The authorization token is verified and needs to accessible to check if the call is itself is authorized.

I used:

ctx := context.WithValue(r.Context(), string("principal_id"), *id) 

But golint complains:

should not use basic type string as key in context.WithValue 

What is the best option that could be used to retrieve this key that is not a basic type like a simple string?

like image 609
snorberhuis Avatar asked Nov 30 '16 14:11

snorberhuis


2 Answers

Just use a key type:

type key int  const (     keyPrincipalID key = iota     // ... ) 

Since you've defined a separate type, it will never collide. Even if you have two packages, pkg1.key(0) != pkg2.key(0).

See also: Go Blog about key collisions in context.

like image 54
Ainar-G Avatar answered Oct 04 '22 08:10

Ainar-G


Use type struct{} much better.

type ctxKey struct{} // or exported to use outside the package  ctx = context.WithValue(ctx, ctxKey{}, 123) fmt.Println(ctx.Value(ctxKey{}).(int) == 123) // true 

Reference: https://golang.org/pkg/context/#WithValue

The provided key must be comparable and should not be of type string or any other built-in type to avoid collisions between packages using context. Users of WithValue should define their own types for keys. To avoid allocating when assigning to an interface{}, context keys often have concrete type struct{}. Alternatively, exported context key variables' static type should be a pointer or interface.

like image 24
F566 Avatar answered Oct 04 '22 07:10

F566