ややめも

アプリ作りたい女子大学院生のめも💁‍♀️

技術メモ
日記
つくったもの
就活の話

GAEでDatastoreに接続時のnot an App Engine contextエラー

GCPを使ってみよう!と思い、Go(フレームワークはgin)を使って動かしていました。
しかし、いざDatastoreに接続しようとすると

not an App Engine contex

のようなエラーがでて動かない…。

調べてみるとこんなissueを発見。

このissueにはappengineを利用してDatastore等を使う場合はこのappengine.Main()を呼び出さなければならないということが書いてありました。
しかしappengine.Main()を加えてもこのエラーが消えず、苦戦していました。




そして先輩にコードみてもらった結果、Goのhttp周りの挙動をちゃんと追っていなかった・ドキュメント読み不足で動いてませんでした。
教えてくれてありがとうございました(T_T)

原因を下に書きます。

❌書いていたコード

// 自分で定義したrouter
r := router()

err := r.Run()	
if err != nil {	
    panic("Can't start server.")	
}

appengine.Main()

⭕動くコード

// 自分で定義したrouterをHandleを使って処理を登録
http.Handle("/", router())
appengine.Main()

動かなかった理由は、ginに実装されているRunメソッドをみてみるとわかる。

// gin.go
func (engine *Engine) Run(addr ...string) (err error) {
	defer func() { debugPrintError(err) }()

	address := resolveAddress(addr)
	debugPrint("Listening and serving HTTP on %s\n", address)
	err = http.ListenAndServe(address, engine)
	return
}

ここでListenAndServeが入っているが、今回はAppengineを使うのでこの部分の動きは不要。
上のコードではr.Run()のところでListenAndServe関数が動いてしまっています。
ということでHandleにhttp.Handleの第二引数に自分で定義したhandlerを登録し、appengine.Main()を呼び出せばok。

ちなみにappengine.Main()の中身はこんな感じ。

// appengine

func Main() {
	MainPath = filepath.Dir(findMainPath())
	installHealthChecker(http.DefaultServeMux)

	port := "8080"
	if s := os.Getenv("PORT"); s != "" {
		port = s
	}

	host := ""
	if IsDevAppServer() {
		host = "127.0.0.1"
	}
	if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil {
		log.Fatalf("http.ListenAndServe: %v", err)
	}
}


ドキュメントちゃんと読んだら載ってますね…。

私は今まで動けばいいやスタンスで色々作っていて、フレームワークを使う際は内部の動きとかを全く理解せずに使ってしまっていました…。
Goなら辿りやすいのでこれからは使うだけじゃなくてもうちょっとソースを読みたいと思います。

そしてGoのhttp周りのメソッド名とか似すぎていて、こんがらがってくるのでこのあたりで読み直した。
journal.lampetty.net
qiita.com


間違ってたら教えてください〜。