メモ：GAE/go Standard環境での最低限の立ち上げ

GAE/Go Standardを触ってみたので、本格的な開発に入る前の立ち上げ部分のメモを残します。

* まず公式のクイックスタートに沿ってやってみる。  
    * [Go App Engine スタンダード環境のクイックスタート  |  Go の App Engine スタンダード環境  |  Google Cloud](https://cloud.google.com/appengine/docs/standard/go/quickstart?hl=ja) 

```
gcloud components install app-engine-go 
go get -u -d github.com/GoogleCloudPlatform/golang-samples/appengine/helloworld/... 
```

- go getなのでGOPATH配下になるので、cdする。ちなみになんかgo getに時間かかるなと思ったら色々sampleがダウンロードされていた。

```
cd ~/_go/src/github.com/GoogleCloudPlatform/golang-samples/appengine/helloworld 
```

- サンプルは以下のように最低限のもの。
    - [golang-samples/appengine/helloworld at master · GoogleCloudPlatform/golang-samples](https://github.com/GoogleCloudPlatform/golang-samples/tree/master/appengine/helloworld)

```
app.yaml 
hello.go 
```

- まずローカル起動してみよう。gcloudのsdkに同梱されているローカル開発用サーバを起動するdev_appserver.pyを使う。

``` 
$ dev_appserver.py app.yaml
ERROR: Python 3 and later is not compatible with the Google Cloud SDK. Please use Python version 2.7.x.

If you have a compatible Python interpreter installed, you can use it by setting
the CLOUDSDK_PYTHON environment variable to point to it.
``` 

* そういえばローカル環境のpythonを3にしていたが、python2.7系でしか使えないようだ。今時ぃ…。 
* COUDSDK_PYTHONという環境変数を指定すればいいらしいはpyenvを使っていたので、`pyenv local`で2.7系のversionを指定してしまう。 

``` 
pyenv local 2.7.15 
``` 
* もう一度起動。 

``` 
$ dev_appserver.py app.yaml 
``` 

* `http://localhost:8080`にアクセスすると、`hello world`と表示される。 続けて実際にgae/standard上にデプロイしてみよう。 
* まずgcloundのアカウントを認証する。 

``` 
gcloud auth login 
``` 

* ブラウザが開くので普通にgoogleアカウントでログインする。 
* ログインが終わったらプロジェクトを作成し、そのプロジェクトを使うように`gcloud config set`する。 

``` 
gcloud projects create sandbox-gaego 
gcloud config set project sandbox-gaego
``` 

* ちなみにプロジェクトIDは 一意なものでなくてはいけない。 これはアカウント内の一意ではなくGoogle 全体の一意な ID になるようにする。 
* 完了したらdeployしてみよう。 

``` 
$ gcloud app deploy
``` 

* もうgaeにdeployされて起動している。サイトを見てみよう。 

``` 
gcloud app browse 
``` 

* ブラウザが開いて`hello,world`と表示されるだろう。 
* さて、ここまではgoogleのサンプル通りなのでうまくいくのは当然だ。 少し修正してみる。 

``` 
$ tree
$GOPATH/src/github.com/roadman/sandbox-gaego/
├── app.yaml
├── main.go
└── handle
     └── hello.go
```

* hello.goに含まれていたhandlerだけhandlerパッケージに分けて、main.goでimportしている。普通のgolangプロジェクトでは１ファイルに全部書くなどということはないので、まあよくある形の簡略化版だ。
* またローカル起動してみると、エラーになる。 

``` 
2018/12/29 16:40:12 go-app-builder: Failed parsing input: app file hello.go conflicts with same file imported from GOPATH
``` 

* これについてはこちらの記事でも解説されているのだが、gae/goではプロジェクトルート（app.yamlのあるディレクトリ）配下の全てのgoファイルを、import対象の別packageであってもbuildしようとするため、conflictが起こるらしい。
    * [Google App EngineでGoを動かすときに知っておくべきこと（ソースコード・ビルド編） - 詩と創作・思索のひろば](https://motemen.hatenablog.com/entry/2016/11/gae-go-building#goapp-%E3%81%AF%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%83%AB%E3%83%BC%E3%83%88%E4%BB%A5%E4%B8%8B%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E3%81%99%E3%81%B9%E3%81%A6%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B) 
* まあ、わざわざ別packageをfullpath指定でimportしているのだから、そういう考え方もあるか、という気もするが、既存のgolangでは普通にある構成なので違和感はある。 
* なので、とりあえず以下のような構成にする。 

``` 
$ tree
$GOPATH/src/github.com/roadman/sandbox-gaego/
├── appengine
│   ├── app.yaml
│   └── main.go
└── handle
     └── hello.go
```

* 再度起動するとうまく起動した。 
* プロジェクトルートをGOPATHに指定する方法もあるが、そうなると他のgolang環境と違うし、ソースコード内で指定するimportのpathがこのプロジェクト専用のものになるのはちょっと気持ち悪い。