まずは app.yaml を作った。
プログラムとHTMLテンプレートを分離したいのでGoの html/template というパッケージを使った。テンプレートはこんな感じ。
このテンプレートを使うプログラムはこんな感じ。
環境変数PORT以外に特にApp Engine特有の機能は使っていないのでローカルマシンで動く。
ローカルマシンで動くのが確認できたらデプロイする。
runtime: go113手元のマシンにインストールされているGo 1.13を使いたいgo113を指定した。
プログラムとHTMLテンプレートを分離したいのでGoの html/template というパッケージを使った。テンプレートはこんな感じ。
<html>
<head><title>Zick's Homepage</title></head>
<body>
<h1>Welcome to Zick's Homepage</h1>
<p>
You are the {{.Counter}} guest!
</p>
<form action="/" method="post">
name:
<input type="text" name="name" /><br />
text:
<textarea name="text" row="4" cols="80"></textarea><br />
<input type="submit" value="submit" />
<table border="1">
{{range .Bbs}}
<tr><td>{{.Date}}</td><td>{{.Name}}</td><td>{{.Text}}</td></tr>
{{end}}
</table>
</form>
</body>
</html>
あえて古臭いHTMLにこだわった。
{{.field}} でテンプレートに渡した構造体のフィールドにアクセスできる。
{{range .repeated_field}} で配列をループで回せる。これでカウンタと掲示板へのすべての書き込みが表示できる。このテンプレートを使うプログラムはこんな感じ。
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"os"
"sync"
"time"
)
type Kakikomi struct {
Date string
Name string
Text string
}
var count = 0
var kakikomis []Kakikomi
var mutex sync.Mutex
type Bindings struct {
Counter string
Bbs []Kakikomi
}
func updateVars(name string, text string) (int, []Kakikomi) {
mutex.Lock()
defer mutex.Unlock()
count++
if name != "" && text != "" {
kakikomis = append(
kakikomis, Kakikomi{time.Now().Format("2006-01-02 15:04"), name, text})
}
return count, kakikomis
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
c, k := updateVars(r.FormValue("name"), r.FormValue("text"))
tpl := template.Must(template.ParseFiles("index.tpl"))
m := Bindings{
Counter: fmt.Sprintf("%dth", c),
Bbs: k,
}
tpl.Execute(w, m)
}
func main() {
http.HandleFunc("/", indexHandler)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
log.Printf("Default to port %s", port)
}
log.Printf("Listening on port %s", port)
if err := http.ListenAndServe(":"+port, nil); err != nil {
log.Fatal(err)
}
}
カウンタと掲示板の書き込みはグローバル変数として持つ。これだとプログラムが再起動するとデータが消えるし、複数インスタンスが立ち上がると整合性が保てなくなるが、遊びなのでヨシ!環境変数PORT以外に特にApp Engine特有の機能は使っていないのでローカルマシンで動く。
go run main.golocalhost:8080にアクセスするとテストができるので便利。
ローカルマシンで動くのが確認できたらデプロイする。
gcloud app deploy無事、App Engine上で動くのが確認できた。よかった。

0 件のコメント:
コメントを投稿