2

我的基本main设置:

muxRouter := mux.NewRouter()

v1Router.Router(muxRouter.PathPrefix("/v1").Subrouter())

http.Handle("/", muxRouter)


n := negroni.Classic()
n.Use(negroni.HandlerFunc(apiRouter.Middleware))
n.UseHandler(muxRouter)

s := &http.Server{
    Addr:           ":6060",
    Handler:        n,
    ReadTimeout:    10 * time.Second,
    WriteTimeout:   10 * time.Second,
    MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())

在里面apiRouter.Middleware我设置了以下上下文:

context.Set(req, helperKeys.DomainName, "some-value")

但是,在某些 handlerFunc 内v1Router.Router尝试获取Get上下文的值时,结果为 nil:

domain := context.Get(req, helperKeys.DomainName)
fmt.Println("DomainName", domain)

印刷:DomainName <nil>

我知道该Set方法是正确的,因为在将其设置后立即获取该值apiRouter.Middleware将返回正确的字符串值。

4

2 回答 2

1

我最终使用了Go 1.7内置的Context

context.Set(req, helperKeys.DomainName, "some-value")

// Replaced with:

ctx := req.Context()
ctx = context.WithValue(ctx, helperKeys.DomainName, "some-value")
req = req.WithContext(ctx)

domain := context.Get(req, helperKeys.DomainName)

// Replaced with:

domain := req.Context().Value(helperKeys.DomainName).(string)
于 2017-02-14T16:27:04.787 回答
0

根据您的回答,您似乎正在尝试在上下文中存储数据库。我不建议这样做。而是尝试这样的事情:

type Something struct {
  DB *sql.DB // or some other DB object
}

func (s *Something) CreateUser(w http.ResponseWriter, r *http.Request) {
  // use s.DB to access the database
  fmt.Fprintln(w, "Created a user...")
}

func main() {
  db := ...
  s := Something{db}
  http.HandleFunc("/", s.CreateUser)
  // ... everything else is pretty much like normal.
}

这使您的处理程序可以访问数据库,而不必每次都在上下文中设置它。上下文值应该保留给那些在运行时才可能设置的东西。例如,特定于该 Web 请求的请求 ID。超过请求的东西通常不属于这一类,并且您的数据库连接将超过请求。

如果您确实需要上下文值,您应该:

  1. 使用输入的 getter 和 setter
  2. “包应该将键定义为未导出的类型以避免冲突。” -来自 Go 源代码

下面显示了一个例子,我在这篇博文中更多地讨论了上下文值:

type userCtxKeyType string

const userCtxKey userCtxKeyType = "user"

func WithUser(ctx context.Context, user *User) context.Context {  
  return context.WithValue(ctx, userCtxKey, user)
}

func GetUser(ctx context.Context) *User {  
  user, ok := ctx.Value(userCtxKey).(*User)
  if !ok {
    // Log this issue
    return nil
  }
  return user
}
于 2017-02-14T18:23:47.320 回答