首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >negroni中间件中的请求上下文集在嵌套的gorilla子路由器中丢失

negroni中间件中的请求上下文集在嵌套的gorilla子路由器中丢失
EN

Stack Overflow用户
提问于 2017-02-14 23:09:22
回答 2查看 549关注 0票数 2

我的基本main设置:

代码语言:javascript
复制
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中,我设置了以下上下文:

代码语言:javascript
复制
context.Set(req, helperKeys.DomainName, "some-value")

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

代码语言:javascript
复制
domain := context.Get(req, helperKeys.DomainName)
fmt.Println("DomainName", domain)

印刷品:DomainName <nil>

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

EN

回答 2

Stack Overflow用户

发布于 2017-02-15 00:27:05

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

代码语言:javascript
复制
context.Set(req, helperKeys.DomainName, "some-value")

// Replaced with:

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

代码语言:javascript
复制
domain := context.Get(req, helperKeys.DomainName)

// Replaced with:

domain := req.Context().Value(helperKeys.DomainName).(string)
票数 1
EN

Stack Overflow用户

发布于 2017-02-15 02:23:47

根据您的回答,看起来您正在尝试在上下文中存储数据库。我不建议这样做。相反,尝试如下所示:

代码语言:javascript
复制
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。存在时间超过请求的事物通常不属于这一类,并且您的DB连接将存在于请求之外。

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

使用typed

  • "packages类型的
  1. 和setter应该将键定义为未导出的类型,以避免冲突。“- From the Go source code

下面显示了一个这样的示例,我将更多地讨论this blog post中的一般上下文值

代码语言:javascript
复制
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
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42229594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档