Go言語のWebアプリケーションフレームワーク「Beego」でゲストブックアプリケーションを作ってみた

GoのwebアプリケーションフレームワークBeego」でPythonプロフェッショナルプログラミングの2章のゲストブックアプリケーションを作ってみた。
(こちらのエントリの真似)

インストール

$ go get github.com/astaxie/beego
$ go get github.com/beego/bee

beeはコマンドラインツールで、プロジェクトの作成や起動を行える。

$ bee help
Bee is a tool for managing beego framework.

Usage:

	bee command [arguments]

The commands are:

    new         create an application base on beego framework
    run         run the app which can hot compile
    pack        compress an beego project
    api         create an api application base on beego framework
    router      auto-generate routers for the app controllers
    test        test the app
    bale        packs non-Go files to Go source files

Use "bee help [command]" for more information about a command.

Additional help topics:


Use "bee help [topic]" for more information about that topic.

プロジェクト作成

beeを使ってプロジェクト作成

$ bee new beeapp
[INFO] Creating application...
/path/to/gopath/src/beeapp/
/path/to/gopath/src/beeapp/conf/
/path/to/gopath/src/beeapp/controllers/
/path/to/gopath/src/beeapp/models/
/path/to/gopath/src/beeapp/routers/
/path/to/gopath/src/beeapp/tests/
/path/to/gopath/src/beeapp/static/
/path/to/gopath/src/beeapp/static/js/
/path/to/gopath/src/beeapp/static/css/
/path/to/gopath/src/beeapp/static/img/
/path/to/gopath/src/beeapp/views/
/path/to/gopath/src/beeapp/conf/app.conf
/path/to/gopath/src/beeapp/controllers/default.go
/path/to/gopath/src/beeapp/views/index.tpl
/path/to/gopath/src/beeapp/routers/router.go
/path/to/gopath/src/beeapp/tests/default_test.go
/path/to/gopath/src/beeapp/main.go
14-01-02 11:42:07 [SUCC] New application successfully created!


生成されたファイル

$ tree
.
├── beeapp
├── conf
│   └── app.conf
├── controllers
│   └── default.go
├── main.go
├── models
├── routers
│   └── router.go
├── static
│   ├── css
│   ├── img
│   └── js
├── tests
│   └── default_test.go
└── views
    └── index.tpl

とりあえず動かす

beeで起動もできる

$ cd beeapp
$ bee run
14-01-02 11:43:53 [INFO] Uses 'beeapp' as 'appname'
14-01-02 11:43:53 [INFO] Initializing watcher...
14-01-02 11:43:53 [TRAC] Directory(/path/to/gopath/src/beeapp/controllers)
14-01-02 11:43:53 [TRAC] Directory(/path/to/gopath/src/beeapp/models)
14-01-02 11:43:53 [TRAC] Directory(/path/to/gopath/src/beeapp)
14-01-02 11:43:53 [INFO] Start building...
14-01-02 11:43:55 [SUCC] Build was successful
14-01-02 11:43:55 [INFO] Restarting beeapp ...
14-01-02 11:43:55 [INFO] ./beeapp is running...
2014/01/02 11:43:55 [I] Running on :8080

ゲストブックアプリケーションを作ってみる

DB接続に必要なパッケージをインストール。

$ go get github.com/astaxie/beego/orm
$ go get github.com/go-sql-driver/mysql


main.goにDBの接続情報や、テンプレートで使う関数を書いてみた。

package main

import (
	"beeapp/models"
	_ "beeapp/routers"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
	"strings"
	"time"
)

// time.Timeオブジェクトを見やすい表示にする関数
func dateformat(in time.Time) (out string) {
	out = in.Format("2006-01-02 15:04:05")
	return
}

// 改行文字をbrタグに置き換える関数
func nl2br(in string) (out string) {
	out = strings.Replace(in, "\n", "<br>", -1)
	return
}

func init() {
	orm.RegisterDataBase("default", "mysql", "user:pass@/beeapp?charset=utf8", 30)
	orm.RegisterModel(new(models.Greeting))

	beego.AddFuncMap("dateformat", dateformat)
	beego.AddFuncMap("nl2br", nl2br)

}

// テーブルがなければ作成する
func syncdb() {
	err := orm.RunSyncdb("default", false, true)
	if err != nil {
		panic(err)
	}
}

func main() {
	syncdb()
	beego.Run()
}


models/models.go
モデル定義

package models

import (
	"time"
)

type Greeting struct {
	Id       int    `orm:"auto"`
	Name     string `orm:"size(100)"`
	Comment  string `orm:"size(200)"`
	CreateAt time.Time
}

routers/router.go
ルーティングの設定を書く。

package routers

import (
	"beeapp/controllers"
	"github.com/astaxie/beego"
)

func init() {
	beego.Router("/", &controllers.MainController{})
	beego.Router("/post", &controllers.GreetingController{})
}


controllers/default.go
ORマッパーでデータ取得して一覧表示する。

package controllers

import (
	"beeapp/models"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
)

// トップページ
type MainController struct {
	beego.Controller
}

func (this *MainController) Get() {
	o := orm.NewOrm()

	var greetings []*models.Greeting
	o.QueryTable("greeting").OrderBy("-CreateAt").All(&greetings)

	this.Data["greetings"] = greetings
	this.TplNames = "index.tpl"
}

controllers/greeting.go
データ投稿用のcontroller。ORマッパーを使ってデータを作成してリダイレクト。
入力チェックは行っていない。

package controllers

import (
	"beeapp/models"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"time"
)

// 投稿
type GreetingController struct {
	beego.Controller
}

func (this *GreetingController) Post() {
	o := orm.NewOrm()
	greet := models.Greeting{
		Name:     this.GetString("name"),
		Comment:  this.GetString("comment"),
		CreateAt: time.Now()}
	o.Insert(&greet)
	this.Ctx.Redirect(302, "/")
}


index.tpl
渡されたデータをループで表示。
モデル定義からフォームのhtmlを生成する機能があるみたいだけど使っていない。

<!DOCTYPE html>
<html>
  <head>
    <title>Beego GuestBook</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="stylesheet" href="/static/css/main.css" type="text/css" />
  </head>
  <body>
    <div id="main">
      <h1>ゲストブック</h1>
      <div id="form-area">
        <p>書き込みをどうぞ。</p>
        <form action="/post" method="post">
          <table>
            <tr>
              <th>名前</th>
              <td>
                <input type="text" size="20" name="name" />
              </td>
            </tr>
            <tr>
              <th>コメント</th>
              <td>
                <textarea rows="5" cols="40" name="comment"></textarea>
              </td>
            </tr>
          </table>
          <p><button type="submit">送信</button></p>
        </form>
      </div>
      <div id="entries-area">
        <h2>これまでの書き込み</h2>
        {{range $key, $val := .greetings}}
        <div class="entry">
          <h3>{{$val.Name}} さんの書き込み({{$val.CreateAt|dateformat}}):</h3>
          <p>{{$val.Comment|htmlquote|nl2br|str2html}}</p>
        </div>
        {{end}}
      </div>
    </div>
  </body>
</html>



雑感

必要な機能はだいたい揃っているように見えた。
ドキュメントもちゃんと書いてあって「これどう書くんだろう?」っていうのは読めばなんとかなった。
使ってないけど、モデル定義からフォームのHTMLを生成とか、バリデーションとかもできるらしい。
goでちょっとしたwebアプリを書きたいときはよさそう。

ソースをgithubにおいた
yuhei0718/beego-guestbook


参考:Bottleとpeeweeを使ってゲストブックアプリケーションを作ってみた - 偏った言語信者の垂れ流し