假设,对于每个请求连接到数据库并在请求完成时关闭是不错的做法?
我正在使用mongodb
和mgo
作为数据库。
在我的项目中,我想通过从请求标头中获取数据库名称来连接到某个数据库(当然,这与身份验证机制相结合,例如我的应用程序中的JWT)。流程如下:
用户身份验证:
POST to http://api.app.com/authenticate
// which checks the user in a "global" database,
// authenticates them and returns a signed JWT token
// The token is stored in bolt.db for the authentication mechanism
一些RESTful操作
POST to http://api.app.com/v1/blog/posts
// JWT middleware for each request to /v1* is set up
// `Client-Domain` in header is set to a database's name, e.g 'app-com'
// so we open a connection to that database and close when
// request finishes
所以我的问题是:
我之所以需要这样做是因为我们有多个供应商拥有相同的数据库集合,这些集合具有不同的条目,并且对自己的数据库具有受限访问权。
更新/解决方案
我最后使用Go
内置的Context
复制会话,并在任何需要做任何CRUD操作的地方使用它
类似的东西:
func main() {
...
// Configure connection and set in global var
model.DBSession, err = mgo.DialWithInfo(mongoDBDialInfo)
defer model.DBSession.Close()
...
n := negroni.Classic()
n.Use(negroni.HandlerFunc(Middleware))
...
}
func Middleware(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
...
db := NewDataStore(clientDomain)
// db.Close() is an alias for ds.session.Close(), code for this function is not included in this post
// Im still experimenting with this, I need to make sure the session is only closed after a request has completed, currently it does not always do so
defer db.Close()
ctx := req.Context()
ctx = context.WithValue(ctx, auth.DataStore, db)
req = req.WithContext(ctx)
...
}
func NewDataStore(db string) *DataStore {
store := &DataStore{
db: DBSession.Copy().DB(db),
session: DBSession.Copy(),
}
return store
}
然后在HandlerFunc中使用它,例如/v1/system/users
:
func getUsers(res http.ResponseWriter, req *http.Request) {
db := req.Context().Value(auth.DataStore).(*model.DataStore)
users := make([]SystemUser{}, 0)
// db.C() is an alias for ds.db.C(), code for this function is not included in this post
db.C("system_users").Find(nil).All(&users)
}
与我实验的原始方法相比,响应时间缩短了40%。
答案 0 :(得分:0)
假设不是一个好习惯,因为:
回答你的问题: