Golang Cafe #34 GAE/G を触る 2014

2014/06/14に開催された「Golang Cafe #34」についてのまとめです。

Golang Cafeも<htmlday> 2014のイベントとして登録しているので、今回はweb寄りなお題ということで、GAE/Gを触ってみるということで、Go Tutorialを進めていきました。


私は以前に、

はじめてのGoogle App Engine Go言語編 (I・O BOOKS)

はじめてのGoogle App Engine Go言語編 (I・O BOOKS)

を読んでいましたので、今回の内容で基本的な部分の復習をさせてもらいました。


詳細な内容はGo Tutorialを実際に読んでもらうとして、ポイントだけ整理しておきたいと思います。

The Development Environment

以前こちらにGolang Cafeを始める前の準備としてまとめて通りなのですが、Python2.7系(3系はダメです)とApp Engine SDK for Goが必要です。
それぞれダウンロードしてインストールしたディレクトリにパスを通しておきます。

Hello, World!

net/httpパッケージの使い方とよく似ています。
ハンドラをinitメソッドで登録するようにするのと、通常のGoのプログラムでは、

http.ListenAndServe(":8080", nil)

と自分で起動する部分を削除するだけです。

application: helloworld
version: 1
runtime: go
api_version: go1

handlers:
- url: /.*
  script: _go_app

versionは文字列でもなんでもいいようです。


チュートリアルでは、

myapp/
  app.yaml
  hello.go // ソースコードではpackage hello となっている

ディレクトリ構成にしていますが、Goの標準(?)にならって、

myapp/
  app.yaml
  hello/
    hello.go

としておくほうが間違いがないと思います。
ハンドラはすべてのファイルに書いてあるものが登録されるようなので、パスに対するハンドラを複数のファイルで重複して定義しないように注意する必要があります。


また、登録していないパスにアクセスされた場合、/(ルート)にフォワードされるようなので、未登録のパスに対しては404を返すなどの対応をしておく必要がありそうです。

Using the Users Service

GAE/GではGoogleユーザアカウントを使って認証することができます。twitterやFafebookでoauthを使って認証することもできますが、実装が非常に簡単です。

// コンテキストの作成
c := appengine.NewContext(r)
// 現在のユーザ情報の取得
u := user.Current(c)
// 未認証の場合はnilになります。
if u == nil {
    // ログインするためのurlを取得できます。
    url, _ := user.LoginURL(c, r.URL.String())

    ...
    // リダイレクト
} else {
    // ログアウトするためのurl
    url, _ := user.LogoutURL(c, "/")
}

Handling Forms

もちろんクライアントのフォームから送信した値を取得することができます。

func sign(w http.ResponseWriter, r *http.Request) {
    err := signTemplate.Execute(w, r.FormValue("content"))
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

html/templateパッケージを使用しているのでエスケープもされます。

Using the Datastore

データストアの基本的な使い方です。

// コンテキストの作成
c := appengine.NewContext(r)
// 登録するためのキーを作成
k := datastore.NewKey(c, "Guestbook", "default_guestbook", 0, nil)
key := datastore.NewIncompleteKey(c, "Greeting", k)
// 登録
_, err := datastore.Put(c, key, &g)

登録が失敗することもあるらしいので、その場合はタスクを使用するなど。

c := appengine.NewContext(r)
// 登録するためのキーを作成
k := datastore.NewKey(c, "Guestbook", "default_guestbook", 0, nil)
// クエリの作成
q := datastore.NewQuery("Greeting").Ancestor(k).Order("-Date").Limit(10)
greetings := make([]Greeting, 0, 10)
// 取得
if _, err := q.GetAll(c, &greetings); err != nil {

登録直後はGetAllでは取得できないのでキーを指定して取得するなど。
データストア特有の気をつけなくてはならない点が多くあるようです。

まとめ

今回は<htmlday> 2014のイベントということでしたので、生成されるページにHTML5を適用させておきました。
次回はGo Conference 2014 springの発表内容をもう少しだけみていくそうです。


GAE/Gに関しては、Golang Cafeに参加中の+TakashiYokoyama氏の書籍もあるのでご参考に。

Go言語プログラミング入門on Google App Engine

Go言語プログラミング入門on Google App Engine