是否应该根据 Google App Engine 的请求创建 Firestore 客户端?



我对如何处理这个问题感到困惑。

GAE 似乎希望每个客户端库都使用上下文。范围限定为 http 的上下文。请求。

我以前有做这样的事情的经验:

主去

type server struct {
db *firestore.Client
}
func main() {
// Setup server
s := &server{db: NewFirestoreClient()}
// Setup Router
http.HandleFunc("/people", s.peopleHandler())
// Starts the server to receive requests
appengine.Main()
}
func (s *server) peopleHandler() http.HandlerFunc {
// pass context in this closure from main?
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() // appengine.NewContext(r) but should it inherit from background somehow?
s.person(ctx, 1)
// ...
}
}
func (s *server) person(ctx context.Context, id int) {
// what context should this be?
_, err := s.db.Client.Collection("people").Doc(uid).Set(ctx, p)
// handle client results
}

Firebase.go

// Firestore returns a warapper for client
type Firestore struct {
Client *firestore.Client
}
// NewFirestoreClient returns a firestore struct client to use for firestore db access
func NewFirestoreClient() *Firestore {
ctx := context.Background()
client, err := firestore.NewClient(ctx, os.Getenv("GOOGLE_PROJECT_ID"))
if err != nil {
log.Fatal(err)
}
return &Firestore{
Client: client,
}
}

这对如何确定项目范围客户的范围有很大的影响。例如,挂在server{db: client}上并在该结构上附加处理程序,或者必须通过请求中的依赖注入将其传递出去。

我确实注意到使用客户端的调用需要另一个上下文。所以也许它应该是这样的:

  1. main.go创建ctx := context.Background()
  2. main.go将其传递给新客户端
  3. handler ctx := appengine.NewContext(r)

基本上,初始设置与context.Background()无关紧要,因为新请求的上下文与 App Engine 不同?

我可以将 ctx 从主传递到处理程序中,然后从该 + 请求的 NewContext 中传递?

对此的惯用方法是什么?

注意:我在以前的迭代中也有Firestore结构中的 firestore 方法......

您应该重复使用firestore.Client实例进行多次调用。但是,这在 GAE 标准的旧 Go 运行时中是不可能的。因此,在这种情况下,您必须为每个请求创建一个新firestore.Client

但是,如果您使用新的 Golang 1.11 运行时作为 GAE 标准,那么您可以自由使用您喜欢的任何上下文。在这种情况下,您可以使用后台上下文在main()函数或init()函数中初始化firestore.Client。然后,您可以使用请求上下文在请求处理程序中进行 API 调用。

package main
var client *firestore.Client
func init() {
var err error
client, err = firestore.NewClient(context.Background())
// handle errors as needed
}
func handleRequest(w http.ResponseWriter, r *http.Request) {
doc := client.Collection("cities").Doc("Mountain View")
doc.Set(r.Context(), someData)
// rest of the handler logic
}

以下是我使用 Go 1.11 和 Firestore 实现的 GAE 应用示例,它演示了上述模式: https://github.com/hiranya911/firecloud/blob/master/crypto-fire-alert/cryptocron/web/main.go

GAE 中的更多移动 1.11 支持:https://cloud.google.com/appengine/docs/standard/go111/go-differences

最新更新