GAE for Go触ってみた

## 参考

* [Quickstart for Mac OS X  |  Cloud SDK Documentation  |  Google Cloud Platform](https://cloud.google.com/sdk/docs/quickstart-mac-os-x?hl=ja)
* [Go+App Engine+Cloud SQLで始めるGo言語Webアプリケーション開発 | eureka tech blog](https://developers.eure.jp/tech/go-appengine-sql-waf/)

## cloud

* google-cloud-sdk-131.0.0-darwin-x86_64.tar.gz を展開して

```bash:
cd ./google-cloud-sdk/
./install.sh

mkdir ~/prj1 && cd ~/prj1
gcloud init
```


## SDKダウンロード

* [Download and Install the SDK for App Engine  |  App Engine Documentation  |  Google Cloud Platform](https://cloud.google.com/appengine/downloads)

* せっかくなのでGoを選択した。

```bash:
brew install go
mkdir ~/vendor/gopath/

export PATH=$PATH:/usr/local/opt/go/libexec/bin
export PATH=$PATH:~/vendor/go_appengine/
export GOPATH=~/vendor/gopath/
```

## app.yamlなど

* [GAE for GOの環境を構築する - Qiita](http://qiita.com/135yshr/items/de2b8cc7ec9ae1ce2cd9)をなぞる。

```bash:
touch app.yaml
touch hello.go
```

```rb:app.yaml
application: helloworld
version: 1
runtime: go
api_version: go1

handlers:
- url: /.*
  script: _go_app
```

```go:hello.go
package hello

import (
    "fmt"
    "net/http"
)

func init() {
    http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
    var html =`
<head>
<link rel="stylesheet" href="https://cdn.rawgit.com/milligram/milligram/master/dist/milligram.css">
<script src="https://cdn.rawgit.com/chjj/marked/master/marked.min.js"></script>
</head>
<body>
<div class="container">
<div id="mdrender"></div>
</div>
<div id="mdraw" style="display:none;">

# 日本語でOK

1. bb

<pre>
1. bb
</pre>

</div>
</body>
<script> document.getElementById("mdrender").innerHTML = marked(document.getElementById("mdraw").innerHTML); </script>
`
    fmt.Fprint(w, html)
}
```

```bash:
goapp serve ./
```

* http://localhost:8080 にアクセスすると`日本語でOK`が確認できる。

## デプロイ

* プロジェクトを用意しておく。[console](https://console.cloud.google.com/projectselector/appengine?hl=ja&pli=1)

```diff:app.yaml
- application: helloworld
+ application: go-2016
```

```
goapp deploy
```

* [gcloud Overview  |  Cloud SDK Documentation  |  Google Cloud Platform](https://cloud.google.com/sdk/gcloud/?hl=ja)

```bash:webブラウザで確認
gcloud preview app browse
```

* https://go-2016.appspot.com/

## htmlをもっと簡単に使う

* 参考: [Reinbach](http://reinbach.com/golang-webapps-1.html)

```go:hello.go
package hello

import (
    "net/http"
    "html/template"
)

func init() {
    http.HandleFunc("/", Home)
}

func Home(w http.ResponseWriter, req *http.Request) {
    render(w, "index.html")
}

func render(w http.ResponseWriter, tmpl string) {
    t, _ := template.ParseFiles("templates/" + tmpl)
    t.Execute(w, "")
}
```

* `templates/index.html` が読み込まれる。


### 静的ファイルを表示する


```go:hello.go
package hello

import (
    "net/http"
    "html/template"
    "io"
    "time"
    "fmt"
)

const STATIC_URL string = "/static/"
const STATIC_ROOT string = "static/"

func init() {
    http.HandleFunc("/", Home)
    http.HandleFunc("/ip", Ip)
    http.HandleFunc(STATIC_URL, StaticHandler)
}

func Home(w http.ResponseWriter, req *http.Request) {
    render(w, "index.html")
}
func Ip(w http.ResponseWriter, req *http.Request) {
    fmt.Fprint(w, req.RemoteAddr)
}
func render(w http.ResponseWriter, tmpl string) {
    t, _ := template.ParseFiles(STATIC_ROOT + tmpl)
    t.Execute(w, "")
}

func StaticHandler(w http.ResponseWriter, req *http.Request) {
    static_file := req.URL.Path[len(STATIC_URL):]
    if len(static_file) != 0 {
        f, err := http.Dir(STATIC_ROOT).Open(static_file)
        if err == nil {
            content := io.ReadSeeker(f)
            http.ServeContent(w, req, static_file, time.Now(), content)
            return
        }
    }
    http.NotFound(w, req)
}
```

* http://localhost:8080/ => ./index.html
* http://localhost:8080/ip => ipアドレス表示
* http://localhost:8080/static/date.html => ./static/date.html