Edited at

Go言語製のWeb Application Framework - Revel - を触る

More than 5 years have passed since last update.


なんとなく

Goに対する熱意が冷めないけどよくわからないので、

どうせならWAFから入って少しずつ学習しよう、と思って調べてみたところ、

Revelというものを見つけた。

http://robfig.github.com/revel/

Play-Frameworkを参考に作られたフレームワークらしい。

どういうもんなのかわからんし、Go言語そんなにしらないし試しにTutorialに書かれてるサンプルのコードスニペットを参考にしながら触ってみよう…

http://robfig.github.com/revel/tutorial/index.html


Go言語のインストールとか

Tutorialに載ってる内容そのまま...

GOPATHの設定。

mkdir ~/gocode

echo 'export GOPATH="$HOME/gocode' >> ~/.zshenv
source ~/.zshenv


homebrew より goをインストール。

brew install go

go getによりリポジトリからrevelをインストール。

go get github.com/robfig/revel

コマンドラインツールのビルド。

cd ~/gocode

go build -o bin/revel github.com/robfig/revel/cmd

$GOPATH/bin以下にコマンドがビルドされているので、PATHを通す。

echo 'export PATH=$PATH:$GOPATH/bin' >> ~/.zshenv

source ~/.zshenv

終わり。


Revelを試してみる

試しにrevelコマンドを叩くとするか。

revel 

revel実行結果

通ってるし大丈夫そう。アプリケーションのスケルトンでも自動生成してみると、、

revel new myapp

revel new myapp 実行結果

$GOPATH/src/myapp にアプリケーションのスケルトンが作成される。

(これについてはIssueでコマンド実行したところにできないの?というのがあったけど、今のところはしょうがないみたい。環境によってビルド先が異なるなどでGOPATHが変わってしまうわけだし…) -> https://github.com/robfig/revel/issues/57

コマンド実行を行うよう促されたので、叩いてみよう。

revel run myapp

revel run myapp 実行結果

立ち上がった。

localhost:9000を表示させた結果


コントローラー(のメソッド)を追加

これだけだと寂しいので、コントローラーを一つ追加してみる。

まずは、$GOPATH/src/myapp/app/controller/app.goの現状。


app.go

package controllers

import "github.com/robfig/revel"

type Application struct {
*revel.Controller
}

func (c Application) Index() revel.Result {
return c.Render()
}


$GOPATH/src/myapp/conf/routes の現状。

# Routes

# This file defines all application routes (Higher priority routes first)
# ~~~~

GET / Application.Index

# Ignore favicon requests
GET /favicon.ico 404

# Map static resources from the /app/public folder to the /public path
GET /public/{<.+>filepath} Static.Serve("public")

# Catch all
* /{controller}/{action} {controller}.{action}

routesに、1つルーティング条件を追加する。

# Routes

# This file defines all application routes (Higher priority routes first)
# ~~~~

GET / Application.Index
GET /welcome-to-underground Application.WelcomeToUnderGround

# Ignore favicon requests
GET /favicon.ico 404

# Map static resources from the /app/public folder to the /public path
GET /public/{<.+>filepath} Static.Serve("public")

# Catch all
* /{controller}/{action} {controller}.{action}

/welcome-to-undergroundを追加しておく。

対応するcontrollerはApplication.WelcomeToUnderGroundとする。

Application.WelcomeToUnderGroundをapp.goに記述する。


app.go

package controllers

import "github.com/robfig/revel"

type Application struct {
*revel.Controller
}

func (c Application) Index() revel.Result {
return c.Render()
}

func (c Application) WelcomeToUnderGround() revel.Result {
return c.Render()
}


c.Render()で、$GOPATH/src/myapp/app/view/Application/WelcomeToUnderGround.htmlを拾いに行こうとするので、

view用のhtmlファイルも用意しとく。


WelcomeToUnderGround.html

<!DOCTYPE html>

<html lang="ja">
<head>
<meta charset="UTF-8"/>
<title>Welcome to underground</title>
</head>
<body>
<h1>Welcome to underground</h1>
<p>そっと耳元で囁く。</p>
</body>
</html>

ここまでやったら、revelを再起動させ、再度ブラウザで確認を行う。

Welcome to underground

キテる…


変化のあるウェブを目指す

変化がないとつまらないから、ボタンを置いてなんか動作するようにしよう。

WelcomeToUnderGround.htmlを以下のように変更する。


WelcomeToUnderGround.html

<!DOCTYPE html>

<html lang="ja">
<head>
<meta charset="UTF-8"/>
<title>Welcome to underground</title>
</head>
<body>
<h1>Welcome to underground</h1>
<p>そっと耳元で囁く。</p>
{{if .flash.success}}
<p>{{.flash.success}}</p>
{{end}}
<form method="POST" action="/no-thank-you">
<button type="submit">No thank you</button>
</form>
</body>
</html>

flash? なにこれ?気にしない!

routesについて/no-thank-youに対応するため、ルーティング条件を追加する。

# Routes

# This file defines all application routes (Higher priority routes first)
# ~~~~

GET / Application.Index
GET /welcome-to-underground Application.WelcomeToUnderGround
POST /no-thank-you Application.NoThankYou

# Ignore favicon requests
GET /favicon.ico 404

# Map static resources from the /app/public folder to the /public path
GET /public/{<.+>filepath} Static.Serve("public")

# Catch all
* /{controller}/{action} {controller}.{action}


app.go

package controllers

import "github.com/robfig/revel"

type Application struct {
*revel.Controller
}

func (c Application) Index() revel.Result {
return c.Render()
}

func (c Application) WelcomeToUnderGround() revel.Result {
return c.Render()
}

func (c Application) NoThankYou() revel.Result {
c.Flash.Success("は?")
return c.Redirect(Application.WelcomeToUnderGround)
}


は?とは何か、というのも気にしない。

revelを再起動させましょう。

/welcome-to-undergroundを叩いてみましょう。

Welcome to underground

ボタンが増えているので、クリックしてみましょう。

Welcome to underground

は?

なにこれ。そう、flashとは、リダイレクトするときにcookieにREVEL_FLASHというキーに対して、

c.Flash.Success(message)を行うと、revel側がクッキーにメッセージを追加してくれる機能なのです。便利。

REVEL_FLASH


余計なこと

ただ…僕の今時点の状態だとrevelのサーバー側の実装は詳しくわからないし、性能その他どうなのかわからないのと、ORMについてgorpにしようかなとかがWishlist書かれている状態だし、この先どうかはわからんけどgithub上でスターが800以上ついてるし(2013年3月20日現在)、ある程度支持されてるフレームワークだと思えます。いいんじゃないんですかね。

コントローラーについては分割していくことが大切で、自分で使いやすい形にするには

app.goに全部書くとページ数増えていけば死ぬのでPadrinoとか他のお気に入りのフレームワークからやりかたをパクって実装すると良いと思います。Validationとかも一応機能としてあるけど、どこまでヘルパーが強力かは使い込んでいない。

...Go言語のGoルーチンについてはなんとなく把握というか他のスレッドに実行を委譲してブロックを避ける、という認識ができてるけど、チャネル型の使い方とかは改めて何か他のものか、revelリポジトリのsamplesにあるchatのソースを見て覚えたほうがよさそうだなと思いました。

要はGo言語学習全然してない。ゼロの状態。

余計でした。