HTML フォームデータの処理(GAE/Go/Gin)

#はじめに
GAEをGinを利用して構築していきます。
[静的コンテンツの配信(GAE/Go/Gin)](https://qiita.com/koshi_an/items/08a6310d052918b8a9f3)の続きです。

流れは、公式サイトの[HTML フォームデータの処理](https://cloud.google.com/appengine/docs/standard/go/building-app/handling-forms?hl=ja)と同じです。


#ソース

今回のフォルダ構成は、以下の通りです。

```
├──  template
│    └── index.html
├──  static
│    ├── style.css
│    └── gcp-gopher.svg
├──  app.yaml
└──  main.go
```

```yaml:app.yaml
runtime: go111

handlers:
- url: /static
  static_dir: static
  
- url: /.*
  script: auto
```

```css:style.css
body {
    font-family: Arial, sans-serif;
    color: blue;
  }
```

Ginを利用しており、GETメソッドと POSTメソッドで呼び出すハンドラーを分けています。

```go:main.go
package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
	"google.golang.org/appengine"
)

type templateParams struct {
	Notice string
	Name   string
}

func main() {
	router := gin.Default()

	router.LoadHTMLGlob("template/*") // 事前にテンプレートをロード(相対パス)

	router.GET("/", indexGetHandle)
	router.POST("/", indexPostHandle)

	http.Handle("/", router) // router.Run(":8080")の代わり
	appengine.Main()         // これがないと動かない
}

func indexGetHandle(c *gin.Context) {
	params := templateParams{}

	c.HTML(http.StatusOK, "top/index", gin.H{
		"params": params,
	})
}

func indexPostHandle(c *gin.Context) {
	params := templateParams{}

	name := c.PostForm("name")
	params.Name = name // Preserve the name field.
	if name == "" {
		name = "Anonymous Gopher"
	}

	if c.PostForm("message") == "" {

		params.Notice = "No message provided"
		c.HTML(http.StatusBadRequest, "top/index", gin.H{"params": params})
		return
	}

	params.Notice = fmt.Sprintf("Thank you for your submission, %s!", name)

	c.HTML(http.StatusOK, "top/index", gin.H{
		"params": params,
	})
}
```

変数指定で、「.params」がないと動作しませんでした。

```html:template/index.html
{{ define "top/index" }}
<!doctype html>
<html>
<head>
  <title>The Gopher Network</title>
  <link rel="stylesheet" type="text/css" href="/static/style.css">
</head>
<body>

<h1>The Gopher Network</h1>

<img id="logo" src="/static/gcp-gopher.svg" width="100">
<!-- [START html_template] -->
{{with .params.Notice}}<div id="notice">{{.}}</div>{{end}}

<form action="/" method="post">
  <div>Name: <input name="name" value="{{.params.Name}}"></div>
  <div>Message: <input name="message"></div>
  <input type="submit">
</form>
<!-- [END html_template] -->

</body>
</html>
{{ end }}
```


#ローカルで実行
`dev_appserver.py app.yaml`

`localhost:8080`  にアクセスすると以下の画面が表示されます。

![スクリーンショット 2019-07-07 15.36.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/799e06fb-3e57-4256-833e-33ec1dd3dd7e.png)


#アプリケーションをデプロイする

`gcloud app deploy`


#アプリケーションを表示する

`gcloud app browse`


その後、`http://[YOUR_PROJECT_ID].appspot.com`で、画面が表示されるかを確認します。

![スクリーンショット 2019-07-07 16.01.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/059a264c-bd78-e375-b036-2d127ec97dd8.png)

メッセージ送付後

![スクリーンショット 2019-07-07 16.01.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/870ba1f3-f009-7751-87ed-4588997cfc68.png)

メッセージ未入力で送付後

![スクリーンショット 2019-07-07 16.01.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/d631199f-e575-b24b-6ca8-f0b6c9dba4cd.png)



#参考
[HTML フォームデータの処理](https://cloud.google.com/appengine/docs/standard/go/building-app/handling-forms?hl=ja)