Last Updated: April 15, 2021
·
312
· Кирилл Кудрявцев

Go context with value

ctx := Pipe(context.TODO(), SetRequestID("some_value"))
...
reqId, _ := GetRequestId(ctx)

Using this code, you can implement a pipe to set safe context values. Also, it gives at least some guarantees that there is value in the context.

const (
    RequestId = iota
    UserId
    UserToken
)

type PipeFunc func(ctx context.Context) context.Context

func Pipe(ctx context.Context, fns ...PipeFunc) context.Context {
    for _, fn := range fns {
        ctx = fn(ctx)
    }

    return ctx
}

func SetRequestID(requestID string) PipeFunc {
    return func(ctx context.Context) context.Context {
        return context.WithValue(ctx, RequestId, requestID)
    }
}

func GetRequestId(ctx context.Context) (string, error) {
    if id, ok := ctx.Value(RequestId).(string); ok {
        return id, nil
    }

    return "", errors.New("empty requestId")
}