LoginSignup
19
20

More than 5 years have passed since last update.

GoのウェブフレームワークRevelを試してみる

Last updated at Posted at 2014-08-02

Go製のウェブフレームワークRevelを試してみる。

サンプルを動かしてみる

$ go get github.com/revel/cmd/revel
$ revel run github.com/revel/revel/samples/chat
~
~ revel! http://revel.github.io
~
2014/08/02 22:18:17 revel.go:320: Loaded module testrunner
2014/08/02 22:18:17 revel.go:320: Loaded module static
2014/08/02 22:18:17 run.go:57: Running chat (github.com/revel/revel/samples/chat) in dev mode
2014/08/02 22:18:17 harness.go:165: Listening on :9000

http://localhost:9000でアクセス出来る。

スケルトンを作成してみる

$ revel new board # $GOPATH # $GOPATH/src/board にスケルトンアプリケーションが作成される

revel run board でサーバが起動する。

ディレクトリ構成

$ tree
.
├── app
│   ├── controllers
│   │   └── app.go
│   ├── init.go
│   ├── routes
│   │   └── routes.go
│   ├── tmp
│   │   └── main.go
│   └── views
│       ├── App
│       │   └── Index.html
│       ├── debug.html
│       ├── errors
│       │   ├── 404.html
│       │   └── 500.html
│       ├── flash.html
│       ├── footer.html
│       └── header.html
├── conf
│   ├── app.conf
│   └── routes
├── messages
│   └── sample.en
├── public
│   ├── css
│   │   └── bootstrap.css
│   ├── img
│   │   ├── favicon.png
│   │   ├── glyphicons-halflings-white.png
│   │   └── glyphicons-halflings.png
│   └── js
│       └── jquery-1.9.1.min.js
└── tests
    └── apptest.go

各種機能概要

Routingの設定

conf/routes に必要なルーティングを設定する

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

module:jobs                                          # Import all routes from the jobs module

GET    /login                 App.Login              # A simple path
GET    /hotels/               Hotels.Index           # Match /hotels and /hotels/ (optional trailing slash)
GET    /hotels/:id            Hotels.Show            # Extract a URI argument
WS     /hotels/:id/feed       Hotels.Feed            # WebSockets.
POST   /hotels/:id/:action    Hotels.:action         # Automatically route some actions.
GET    /public/*filepath      Static.Serve("public") # Map /app/public resources under /public/...
*      /debug/                module:testrunner      # Prefix all routes in the testrunner module with /debug/
*      /:controller/:action   :controller.:action    # Catch all; Automatic URL generation

例えば /hello にアクセスした時にページを表示させたい場合は

GET /hello Hello.Index

と書く。

Controllers

app/controllers/ 以下にcontroller用のファイルを置く

app/controllers/hello.go
package controllers

import "github.com/revel/revel"

type Hello struct {
  *revel.Controller
}

func (h Hello) Index() revel.Result {
  return h.Render()
}

Templates

app/views/以下にいわゆるViewファイルを置いていく。
デフォルトでは、app/views/#{controller名}/#{action名}.htmlになる。

app/views/Hello/Index.html
{{set . "title" "Hello"}}
{{template "header.html" .}}

<header class="hero-unit" style="background-color:#A9F16C">
  <div class="container">
    <div class="row">
      <div class="hero-text">
        <h1>Hello World!</h1>
        <p></p>
      </div>
    </div>
  </div>
</header>

<div class="container">
  <div class="row">
    <div class="span6">
      {{template "flash.html" .}}
    </div>
  </div>
</div>

{{template "footer.html" .}}

この時点で、$ go run board でサーバー起動し
http://localhost:9000/helloにアクセスすれば上のページが表示される。

Interceptors

Interceptorsはcontrollerメソッドの前後やpanic時、
複数のcontrollerからアクセスがある場合に利用する。

app/controllers/init.go
package controllers

import (
  "fmt"

  "github.com/revel/revel"
)

type Intercepter struct {
}

func (i *Intercepter) Before() revel.Result { // 返り値は `revel.Result`
  fmt.Println("Before Method")
  return nil
}

func (i *Intercepter) After() revel.Result {
  fmt.Println("After Method")
  return nil
}

func (i *Intercepter) Panic() revel.Result {
  fmt.Println("Panic Method")
  return nil
}

func init() {
  revel.InterceptMethod((*Intercepter).Before, revel.BEFORE) // コントローラ実行前
  revel.InterceptMethod((*Intercepter).After, revel.AFTER)       // コントローラ実行後
  revel.InterceptMethod((*Intercepter).Panic, revel.PANIC)      // panic実行後     
}

設定はControllerで行う。

app/controllers/app.go
package controllers

import "github.com/revel/revel"

type App struct {
  *revel.Controller
  Intercepter // 構造体に追加
}

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

Filters

revelのフィルターは、アプリケーションのミドルウェアのことを指す。
revel newで作った場合いくつかapp/init.goに書かれている

app/init.go
  revel.Filters = []revel.Filter{
    revel.PanicFilter,             // Recover from panics and display an error page instead.
    revel.RouterFilter,            // Use the routing table to select the right Action
    revel.FilterConfiguringFilter, // A hook for adding or removing per-Action filters.
    revel.ParamsFilter,            // Parse parameters into Controller.Params.
    revel.SessionFilter,           // Restore and write the session cookie.
    revel.FlashFilter,             // Restore and write the flash cookie.
    revel.ValidationFilter,        // Restore kept validation errors and save new ones from cookie.
    revel.I18nFilter,              // Resolve the requested language
    HeaderFilter,                  // Add some security based headers
    revel.InterceptorFilter,       // Run interceptors around the action.
    revel.CompressFilter,          // Compress the result.
    revel.ActionInvoker,           // Invoke the action.
  }

以下の図のFilters部分をここで定義していく

RevelDesign.png
http://revel.github.io/manual/concepts.html

例えば、一つ目のPanicFilterはこんなように書かれている。

github.com/revel/revel/panic.go
// PanicFilter wraps the action invocation in a protective defer blanket that
// converts panics into 500 error pages.
func PanicFilter(c *Controller, fc []Filter) {
  defer func() {
    if err := recover(); err != nil {
      handleInvocationPanic(c, err)
    }
  }()
  fc[0](c, fc[1:])
}

Filterの定義は type Filter func(c *Controller, filterChain []Filter)
最後に fc[0](c, fc[1:])で次のフィルターに実行を移している。

(続きます)

19
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
20