Golang1.8+echo+GoLandでGoogle App Engineのローカルサーバーを実行できる環境を作る


概要

以前にも Go言語初心者がGAE+Echo(v2)+goonでサーバーを構築する という記事を投稿したのですが、appcfg.py の古い方法でビルドやデプロイをしていたりしたことから、再度開発環境を構築してみたのでそれをまとめます。
(まだ gcloud でのデプロイは失敗するけど、 goapp でデプロイできてるからもうそれでOKということで)

前提

MacOS にて、以下のバージョンで構築した内容です。
また、Google Cloud SDK、GoLandなど以下の一通りのものは入れている前提です。

  • GoLand v2017.3
  • Go v1.8
  • direnv
  • glide
  • Google Cloud SDK v192.0.0

Google Cloud SDKでインストールしてるのは以下の感じです。

$ goapp version
go version 1.8.5 (appengine-1.9.67) darwin/amd64

$ gcloud components list
Your current Cloud SDK version is: 192.0.0
The latest available version is: 192.0.0

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                  Components                                                 │
├───────────────┬──────────────────────────────────────────────────────┬──────────────────────────┬───────────┤
│     Status    │                         Name                         │            ID            │    Size   │
├───────────────┼──────────────────────────────────────────────────────┼──────────────────────────┼───────────┤
│ Not Installed │ Cloud Bigtable Command Line Tool                     │ cbt                      │   4.0 MiB │
│ Not Installed │ Cloud Bigtable Emulator                              │ bigtable                 │   3.8 MiB │
│ Not Installed │ Cloud Datalab Command Line Tool                      │ datalab                  │   < 1 MiB │
│ Not Installed │ Cloud Datastore Emulator                             │ cloud-datastore-emulator │  17.9 MiB │
│ Not Installed │ Cloud Datastore Emulator (Legacy)                    │ gcd-emulator             │  38.1 MiB │
│ Not Installed │ Cloud Pub/Sub Emulator                               │ pubsub-emulator          │  33.4 MiB │
│ Not Installed │ Emulator Reverse Proxy                               │ emulator-reverse-proxy   │  14.5 MiB │
│ Not Installed │ Google Container Local Builder                       │ container-builder-local  │   3.7 MiB │
│ Not Installed │ Google Container Registry's Docker credential helper │ docker-credential-gcr    │   2.5 MiB │
│ Not Installed │ gcloud Alpha Commands                                │ alpha                    │   < 1 MiB │
│ Not Installed │ gcloud Beta Commands                                 │ beta                     │   < 1 MiB │
│ Not Installed │ gcloud app Java Extensions                           │ app-engine-java          │ 118.9 MiB │
│ Not Installed │ gcloud app PHP Extensions                            │ app-engine-php           │  21.9 MiB │
│ Not Installed │ gcloud app Python Extensions (Extra Libraries)       │ app-engine-python-extras │  27.8 MiB │
│ Not Installed │ kubectl                                              │ kubectl                  │  12.2 MiB │
│ Installed     │ App Engine Go Extensions                             │ app-engine-go            │ 151.3 MiB │
│ Installed     │ BigQuery Command Line Tool                           │ bq                       │   < 1 MiB │
│ Installed     │ Cloud SDK Core Libraries                             │ core                     │   7.3 MiB │
│ Installed     │ Cloud Storage Command Line Tool                      │ gsutil                   │   3.3 MiB │
│ Installed     │ gcloud app Python Extensions                         │ app-engine-python        │   6.2 MiB │
└───────────────┴──────────────────────────────────────────────────────┴──────────────────────────┴───────────┘
To install or remove components at your current SDK version [192.0.0], run:
  $ gcloud components install COMPONENT_ID
  $ gcloud components remove COMPONENT_ID

To update your SDK installation to the latest version [192.0.0], run:
  $ gcloud components update

※ Google Cloud SDK、direnv、glideのインストール手順は前回の記事にまとめてます。

Goプロジェクトの作成

基本的には、echo+GAEのサンプル を見ながら作成してます。
フォルダ構成としてはこんな感じ。

・root
├・src
│└・gae_test
│ ├vendor ※glideで作成される依存ライブラリ
│ ├glide.lock ※glideでインストールしたら自動でできるアレ
│ ├glide.yaml
│ └main.go ※表示
├.envrc
├.gitignore
└・app.yaml

GoLandの設定

GoLandでAppEngineのローカルビルドができるように設定します。

GOROOTの設定

Goland -> Preferences... から環境を選択します。

GOROOTには、Google Cloud SDK内のGoAppEngineの1.8を選択します。

ちなみに、これを選択しないと、 RunConfiguration を作成する際に以下のように「は?あんたのGO SDKはAppEngineのじゃねーから。」ってバカにされます。

GOPATHの設定

同じく、 Preferences... から設定します。
普通にプロジェクト直下を入れましょう(上に書いた例でいうとroot直下)

依存ライブラリを入れる

こんな感じの設定をしてます(色々と実装を進めた後に備忘で書いてるんで、今回やるだけのことなら必要のないライブラリばっかですけど。。。)。

package: XXXXXX
import: 
- package: github.com/labstack/echo
  version: v3.2.6
  subpackages:
  - engine/standard
  - middleware
- package: github.com/mjibson/goon
- package: golang.org/x/net
  subpackages:
    - context
- package: github.com/golang/protobuf/proto
- package: google.golang.org/appengine
  subpackages:
    - log
    - blobstore
    - datastore
    - mail
    - urlfetch
    - user
- package: github.com/labstack/gommon
  subpackages:
    - log
    - color
- package: github.com/dgrijalva/jwt-go
- package: github.com/favclip/testerator
- package: github.com/lestrrat/go-jwx
- package: github.com/go-playground/validator
  version: v9

あとは、glide.yamlがある場所までいき、以下のコマンドを打って依存ライブラリを入れます。

$ glide update

app.yamlの作成

以下のように作成します。

application: *****
module: default
version: 1
runtime: go
api_version: go1.8

handlers:
- url: /.*
  script: _go_app
skip_files:
- (.*/)?vendor/(.*/)?

main.goのコード

ただ動かしたいだけなら、以下の感じでOKそうです。

package main

import (
    "github.com/labstack/echo"
    "net/http"
    "github.com/labstack/echo/middleware"
)

var e = createMux()

func init() {
    ah := e.Group("/_ah")
    ah.GET("/start" , func(c echo.Context) error { return c.String(http.StatusOK, "")})

    g := e.Group("/hello")
    g.GET("" , func(c echo.Context) error {
        return c.String(http.StatusOK , "hello world!")
    })
}

func createMux() *echo.Echo {
    e := echo.New()

    http.Handle("/", e)
    return e
}

以前は、 middleware.Logger() とか色々なものが必要だったんですけど、そういうのはAppEngine側でラップされてるからいらないよ、らしいです。

Run Configurationの設定

次に、実際にGolandで動かすための設定を作成します。
設定内容は画像をご確認下さい。

この中で、 --debug は、別に設定しても今のところ意味ないです(後述)。
実際に動かしてみると、ちゃんと実行されるかと思います(きっと)。

課題

GAEでのデバッグができない

致命的なんですけど、デバッグでrunすると途中でデバッガが強制終了してしまいます。
デバッグ機能自体は SDK v1.9.61 以降から --debug というオプションが対応したっぽいのでDelveやdebを利用すればできそうなのですが、Golandでそれらを利用する方法がまだわかってません。
まあできるってことはわかったから必要になったらコード上でデバッグでもいいかな。。。

やり方がわかったりしたら、この記事を更新するかも・・・?