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

# 概要
以前にも [Go言語初心者がGAE+Echo(v2)+goonでサーバーを構築する](https://qiita.com/brbranch/items/da656fd12a3177e60bb9 ) という記事を投稿したのですが、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のインストール手順は[前回の記事](https://qiita.com/brbranch/items/da656fd12a3177e60bb9)にまとめてます。

# Goプロジェクトの作成
基本的には、[echo+GAEのサンプル](https://echo.labstack.com/cookbook/google-app-engine) を見ながら作成してます。
フォルダ構成としてはこんな感じ。

```
・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を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/163629/3641ddee-4610-a414-2b2c-bcd9a684bb2e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/163629/dd5bf9e9-b67a-d67c-fc7e-f772581652a7.png)

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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/163629/836a7c23-f6e5-8228-97d1-eb41b3871f9e.png)

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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/163629/68021f3a-5020-c79c-8242-905c1d4c9ab5.png)

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

```yaml
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がある場所までいき、以下のコマンドを打って依存ライブラリを入れます。

```bash
$ glide update
```
## app.yamlの作成
以下のように作成します。

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

handlers:
- url: /.*
  script: _go_app
skip_files:
- (.*/)?vendor/(.*/)?
```
## main.goのコード
ただ動かしたいだけなら、以下の感じでOKそうです。

```go
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で動かすための設定を作成します。
設定内容は画像をご確認下さい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/163629/c87bc546-4213-13de-bd0e-30441746eb01.png)

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

# 課題

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

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