Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
20
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

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

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:])で次のフィルターに実行を移している。

(続きます)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
20
Help us understand the problem. What are the problem?