ふと, Google App Engine(GAE)を試してみたかったのでなにか作ろうと思った.
「掲示板が作れれば大体なんとかなる」とか言いますし,とりあえず掲示板を作りました.
出来たものは以下.適当に時間が経って邪魔になったら多分インスタンス消します.
ソースコードは以下です.
あとは以下の感じで覚書です.
- 環境構築の方法
- Hello,worldする
- デプロイしてHello,worldする
- Datastoreを使う(掲示板アプリのちょっとした解説)
1. 開発環境の構築
やることは以下です.
流石にGoogleアカウントが無いってことはないだろうということで,SDKだけメモります. ちなみに試した環境はUbuntu16.04 LTSです.
1-1. SDKをダウンロード
以下にリンクがあるのでダウンロードします.
ちなみにクイックスタートなのでここの通りにやればHello, world出来ます.流石Googleです.
1-2. 解凍して配置
ダウンロードしたディレクトリを解凍して,適当な場所に配置します. 僕は面倒なのでHOMEに直で置きました.
1-3. PATHの設定
上記までで解凍・配置したディレクトリにパスを通します. 僕の場合は.bashrcに以下を書いています.
export PATH=$PATH:$HOME/go_appengine
ここまでで完了ですが,念の為コマンドを動かしておきます.
$ goapp version
上記でダメな場合はPythonのバージョンが大事なそうなので確認するほうがよいかもしれません.
/usr/bin/env python -V
公式曰く, 2.7系でないとダメだそうです.
2. Hello worldする
公式に記載がありますが,一応書いておきます.
GitHub - GoogleCloudPlatform/appengine-guestbook-go at part1-helloworld
転載させてもらうと以下の通りの非常に普通のgoコードです.
package hello import ( "fmt" "net/http" ) func init() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello, world!") }
これを書いて以下のように配置します.
go_appengine(DLして解凍してPATH通したディレクトリ) | |_ goroot | |_hello | |_ hello.go |_ app.yaml
helloディレクトリの下へ移動して以下のコマンドを実行するとローカルで動作確認ができます.
$ goapp serve
あとはlocalhost:8000へアクセスすれば世界に挨拶できます.
3. GAE上でHello worldする
3-1.プロジェクトを作る
Google Cloud Consoleへアクセスしましょう.
IAMと管理 => すべてのプロジェクト => プロジェクトの作成
でプロジェクトが作れます.
ここで作成したプロジェクトIDをapp.yamlに記述することになります.
3-2. デプロイ
まず,app.yamlを編集します.
application: [登録したプロジェクトID] version: 1 runtime: go api_version: go1 handlers: - url: /.* script: _go_app
公式だとappcfg.pyを使えとなってますね.
僕は色々な他サイトも合わせて見ていたので直接yamlを編集しました.
あとはデプロイのコマンドをコンソールから入力するだけです.
$ goapp deploy
初回は認証が必要です.
デプロイが済んだら以下のようなURLでアクセスします.
http://[登録したプロジェクトID].appspot.com/.
これでGAE上でHello worldできます.
4.Datastoreを使う(掲示板アプリの解説を若干)
ここまで来ると普通のgolangでのWebアプリケーション開発と変わらないのですが, データの永続化にDatastoreを使うのにはやはり少し調べる必要がありました.
とはいえまぁ,安いのでDatastoreを使うのは良いかと思います. 安いし早いし癖はありますが良いみたいですので.なにせ無料枠がありますからね.
App Engine の料金 | App Engine Documentation | Google Cloud Platform
CRUDが出来ればなんとかなるはずなのでコードを記載して簡単にメモ書きしておきます. 詳細は冒頭でリンクを貼ったGitHubのリポジトリへどうぞ.
なお,以下のコードは下記の構造体が用意されていることが前提です.
type Comment struct { Id int64 `datastore:"-"` HandleName string Comment string Like int64 EntryTime time.Time }
また,GAE on Goではリクエストパラメータからコンテキストを生成して,これをたらい回しにして 使うことになります.
c := appengine.NewContext(r)
なので以下のコードでcという名の変数があればすべてコンテキストです.
4-1. Create
var com *Comment key := datastore.NewIncompleteKey(c, "comment", nil) key, err := datastore.Put(c, key, com)
NewIncompleteKeyメソッドでコンテキストとkind(2番目のパラメータ.テーブル名みたいなもん)を渡して上げてキーを作成します. その後Putメソッドでキー・バリューを対応付けして値を登録といった感じ.
4-2. Refere(複数件)
q := datastore.NewQuery("comment").Order("-EntryTime") comments := make([]Comment, 0) iter := q.Run(c) for { var com Comment key, err := iter.Next(&com) if err == datastore.Done { break } else if err != nil { return nil, err } com.Id = key.IntID() comments = append(comments, com) }
NewQueryでkind指定ですべて取得しています.
Orderでソートできますが,先頭に-をつけると降順になるようです.
Queryを実際に実行するにはq.Runでイテレータを取って,iter.Nextで実際に値を取得します.
イテレータの完了はdatastore.Doneをiter.Nextの戻り値のerrと比較すれば判断出来ます.
iter.NextはKeyも返しますが,key.IntIDでキーのint値を得ることができます.
これで特定の値を一意に特定できるのでフォームに埋め込んでやったりと何かと便利です.
4-3. Refere(単一)
keyInt, err := strconv.ParseInt(keyStr, 10, 64) if err != nil { return err } key := datastore.NewKey(c, "comment", "", keyInt, nil) var com Comment err = datastore.Get(c, key, &com)
単一のデータを得るときにはキーIDからキーオブジェクトを新たに作成し(NewKey)これを使ってGetを呼び出すことで得られます.
キーIDは上記のkey.IntIDでの情報ですね.
4-4. Update
RefereとCreateの組み合わせなので省略
4-5. Delete
q := datastore.NewQuery("comment").Filter("__key__=", key).KeysOnly() iter := q.Run(c) var com Comment _, err = iter.Next(&com) if err == datastore.Done { return fmt.Errorf("key not found") } if err != nil { return err } if err = datastore.Delete(c, key); err != nil { return err }
Deleteを使います.
削除するオブジェクトのキーを得るのに上記のコードではNewQueryでFilterを利用しています.
Filterはその名の通り構造体のメンバでフィルターをかけれるメソッドですが, keyは予約語になっていて キーとマッチさせるようです.
またKeysOnlyメソッドを使っていますが,これはキーのみを取得するため,若干パフォーマンスが良くなるようです.
その他
開発中,ローカルでデータを見たくなると思いますが,そんな時は
$ goapp serve
の後に
localhost:8080
へブラウザでアクセスするとローカルのDatastoreの中身を見ることができてとても便利です.
まとめ
解説らしい解説をほぼ入れていないので, 実際はソースを見て頂きたいところです.
とはいえ
- 割と簡単に使えて
- (ある程度は)無料で
- パフォーマンスも良い(課金すれば青天井)
というのは素晴らしい環境です.