golangのWebフレームワーク、revelの機能紹介

golangでのweb application frameworkはいろいろなものがあります。その中 でどれがいいのかというと、どれも鋭意開発途中だし、新しいのも出てくるし でなんとも言えません。

その中で、 revel というフレームワークが結 構昔からあります。これは、Railsに例えられるようになんでも揃ってるいわ ゆ る重量級なフレームワークです。

薄いフレームワークであれば、標準のnet/httpでもいいような気もちょっとす るので、現在このrevelを使って実際に作ってみています。

なお、以下のページを参考にさせていただきました。

特徴

いろいろな特徴がありますが、上記サイトでは挙げられていないrevelのいい ところをここでは紹介してみます。

  • コマンド一発でデプロイ用zipファイルが出来上がる

  • i18n対応

  • いろいろなところにhookを仕込める

  • dev/prodなど実行環境を指定できる。しかもconfigも簡単に書ける

ほかにもredisも対応しているsession管理やjob実行やvalidation、WebSocket 対応などいろいろあるのですが、そこは マニュアル を見て頂くとより分かりやすいかと思 い ます。

コマンド一発でデプロイ用zipファイルが出来上がる

revel package コマンドを実行すると、 tar.gzファイルが出来上がりま す。 これをサーバーに送って展開すると、

.
|-- run.bat
|-- run.sh
|-- sample-app
|-- sample-app.log
|-- sample-app.tar.gz
`-- src
    `-- github.com
        |-- revel
        `-- tsukinowasha
             `-- sample-app

という感じでファイルが展開されます。あとは run.sh を実行すれば、す ぐに実行できます。

ちなみにsrc以下はrevelとアプリだけです。それ以外は含まれていません。 revel以下にはconfファイルやtemplateファイルなどがあり、バイナリやgoファ イルなどは含んでいません。アプリ以下はgoファイルも含めて全部入っていま す。revelは実行時にbuildするのでこれは仕方ないかな、と思います。

bindata で一つのバイナリに パッケージするという方式の方が良いかもしれませんが、この方式でも問題な いかなぁと思っているところです。ただ、 revel package 方式はソースコー ドも含まれているので、それはまずいということであればbindataを使うほうが いいと思います。

i18n対応

message/labes.jamessage/labes.ja というファイルを用意してお くと、ブラウザの言語設定に従ってそのメッセージを返してくれます。

messages.jaは以下の様なファイルです。(別に.で区切らなくても一意であれば 構いません)

mode.dev.label=検証系
login.title=ログイン

こうしておいて、テンプレートで

<h3>{{msg . "login.title" }}</h3>

などと書けば、言語によってmessages.jaやmessages.enの内容を参照してくれ ます。

hook

revelは Interceptor という、リクエスト中のいろんなタイミングに仕込め るHookがあります。

例えば、以下のようにしておくと、リクエストの処理をする前にcheckUser関 数が走ります。

func checkUser(c *revel.Controller) revel.Result {
    if user := connected(c); user == nil {
       c.Flash.Error("Please log in first")
       return c.Redirect(App.Index)
    }
  return nil
}

func init() {
   revel.InterceptFunc(checkUser, revel.BEFORE, &Users{})
}

revel.BEFORE がタイミングの指定です。他にはAFTERやpanic時に呼び出 されるPANICなどがあります。

これを利用すると記述が共通化出来て便利です。

実行環境制御

revel run コマンドで実行すると dev モードで立ち上がり、ログ表示 が詳細になったりhot reloadingが有効になったり、デバッグ表示が出たりし ます。

この辺りは conf/app.conf に書かれてあります。

[dev]
mode.dev=true
results.pretty=true
watch=true

db.host = localhost

[prod]
mode.dev=false
results.pretty=false
watch=false

db.host = prod-db.example.com

このように、セクションで区切ることで、実行環境を選択できます。 [staging] などを追加することも出来ます。これによって動作を変えるこ とが出来ます。

db.host という部分は自分で足したものです。codeの中からは

dbhost := revel.Config.StringDefault("db.host", "localhost")

というように取得できますので、これを使えば環境ごとに違うホストにつなぎ にいく、ということができます。(上記例はdefaultをlocalhostに設定してい ます)

ちなみに、上記 revel package コマンドでパッケージを作成すると、 prod環境で立ち上がるようにスクリプトが作成されています。ちょっとした気 遣いが便利。

テンプレートでのCustom Functions

こんな感じで revel.TemplateFuncs に関数を定義しておけば、template で 使えます。

func init() {
             revel.TemplateFuncs["eq"] = func(a, b interface{})
             bool { return a == b }
}

ハマったところ

最後にrevelを使う時にハマったところを紹介します。といっても今のところ 一つぐらいしかないですが。そのうち更新します。

initタイミング

package内の変数を起動時に書き換えようとしたら、ちゃんと変更してくれま せんでした。OnAppStartで指定することでちゃんと変更されるようになりまし た。

var DB = "localhost"

func init() {
   // これは期待通りに動かない
   // DB := revel.Config.StringDefault("db.host", "localhost")
   revel.OnAppStart(changeDBHostFunc)  // 関数を登録
}

まとめ

今回の記事ではrevelのいろいろな機能を紹介しました。結構便利ではないでしょうか。

revelは重量級と言われるだけあり、機能が豊富です。revelはぼくにとっては 学習コストはさほど高いものではなく、かなりすんなり使いはじめることが出 来ました。そうなると、機能を自分で実装したり後から足すことはない分、楽 に開発ができています。

なお、同じ位置づけのものとしては beego がありますが、こちらはまだ試していません。

Comments

comments powered by Disqus