gcpug / nouhau

Google Cloud Platformのノウハウを共有するRepository
https://gcpug.jp
MIT License
653 stars 23 forks source link

Google App Engine Go 1.11で "google.golang.org/appengine" を利用する場合、必ず appengine.Main() を呼ぶ必要がある #71

Open sinmetal opened 5 years ago

sinmetal commented 5 years ago

WHAT

Go 1.11の最もシンプルな公式のサンプルでは、 google.golang.org/appengine は使っておらず、 http.ListenAndServe を普通に使っている。

https://github.com/GoogleCloudPlatform/golang-samples/blob/28db7057e0a97a7b724da148177e4bc3a48e294f/appengine/go11x/helloworld/helloworld.go#L21

google.golang.org/appengine packageを使わない場合、上記でも問題なく動作するが、 google.golang.org/appengine packageを利用して、DatastoreやMemcacheなどを利用する場合、最初に必ず appengine.Main() を呼ぶ必要がある。

package main

import (
    "net/http"

    "google.golang.org/appengine"
)

func main() {
    http.HandleFunc("/", handler)

    appengine.Main()
}

appengine.Main() を呼んでいない場合、DatastoreやMemcacheを利用する時に not an App Engine context でエラーとなる。

WHY

appengine.Main() の中でHTTP Handlerをセットする時に、appengine.Contextを設定するようになっている。 https://github.com/golang/appengine/blob/ae0ab99deb4dc413a2b4bd6c8bdd0eb67f1e4d06/internal/api.go#L93

ドキュメント的には https://cloud.google.com/appengine/docs/standard/go111/go-differences#writing_a_main_packageOr, if your service is using the google.golang.org/appengine package, include a call to appengine.Main(). と書いてある。