Go 1.14 が一般提供になりました。

App Engine アプリを Go 1.12 以降に移行する

既存の App Engine アプリを Go 1.9 ランタイムから、App Engine スタンダード環境の Go 1.12 以降のランタイムに移行する方法について説明します。

App Engine Go 1.12 以降のランタイムにおける変更点

App Engine Go 1.12 以降のランタイムを使用するには、既存の App Engine Go アプリとデプロイ プロセスを変更する必要があります。新しいランタイムの主な相違点は次のとおりです。

App Engine Go SDK からの移行

appengine パッケージと google.golang.org/appengine パッケージはサポートされなくなりました。同等の Google Cloud サービスにアクセスするには、Google Cloud クライアント ライブラリに移行する必要があります。

app.yaml ファイルの変更

app.yaml 構成ファイルの一部の要素の動作が変更されました。

要素 変更タイプ 説明
api_version 非推奨
runtime 修正 runtime 要素を [Go 1.12 以降を指定](/appengine/docs/standard/go/config/appref#runtime)に変更します。
application_readable 非推奨
builtins 非推奨
includes 非推奨
login 非推奨 Go 1.12 以降のランタイムは login をサポートしていません。ユーザー認証に別の方法を使用する必要があります。
libraries 非推奨
threadsafe 非推奨 すべてのアプリケーションがスレッドセーフ(つまり、インスタンスが複数のリクエストを同時に処理できる)とみなされます。
skip_files 非推奨 代わりに、app.yaml ファイルがあるルート ディレクトリに .gcloudignore ファイルを作成します。詳細については、.gcloudignore リファレンスをご覧ください。

詳細については、app.yaml リファレンスをご覧ください。

main パッケージを作成する

サービスのソースファイルのうち少なくとも 1 つに package main ステートメントを含める必要があります。

main パッケージを記述する

サービスに main パッケージがない場合は、package main ステートメントを追加し、main() 関数を記述します。少なくとも、次の main() 関数が必要です。

  • PORT 環境変数を読み込み、http.ListenAndServe() 関数を呼び出す。

    port := os.Getenv("PORT")
    if port == "" {
    	port = "8080"
    	log.Printf("Defaulting to port %s", port)
    }
    
    log.Printf("Listening on port %s", port)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
    	log.Fatal(err)
    }

HTTP ハンドラを登録する

HTTP ハンドラを登録するには、次のいずれかの方法を選択します。

  • 推奨される方法は、すべての http.HandleFunc() 呼び出しをパッケージから main パッケージの main() 関数に手動で移動する方法です。
  • アプリケーションのパッケージを main パッケージにインポートし、各 init() 関数(http.HandleFunc() への呼び出しを含む)が起動時に実行されるようにする方法もあります。

    次の bash スクリプトを使用すると、http.HandleFunc() 呼び出しを使用するすべてのパッケージを検索して、出力を main パッケージの import ブロックにコピーできます。

    gp=$(go env GOPATH) && p=$(pwd) && pkg=${p#"$gp/src/"} && find . -name "*.go" | xargs grep "http.HandleFunc" --files-with-matches | grep -v vendor/ | grep -v '/main.go' | sed "s#\./\(.*\)/[^/]\+\.go#\t_ \"$pkg/\1\"#" | sort | uniq
    

ファイルの構造化

Go では、パッケージごとにディレクトリを作成する必要があります。プロジェクトの app.yaml ファイルで main: を使用して、main パッケージの場所について App Engine に通知できます。たとえば、アプリのファイル構造が次のようになっているとします。

myapp/
├── app.yaml
├── foo.go
├── bar.go
└── web/
    └── main.go

app.yaml ファイルは次のようになります。

main: ./web # Relative filepath to the directory containing your main package.

main フラグの詳細については、app.yaml リファレンスをご覧ください。

GOPATH へのファイルの移動

次のコマンドを使用して、GOPATH を見つけます。

go env GOPATH

関連するすべてのファイルを移動し、GOPATH にインポートします。import ./guestbook のような間接的なインポートを行う場合は、完全なパス import github.com/example/myapp/guestbook を使用するようにインポートを更新します。