Skip to content

Latest commit

 

History

History
374 lines (267 loc) · 13.8 KB

README_ja_JP.md

File metadata and controls

374 lines (267 loc) · 13.8 KB

Negroni GoDoc wercker status codebeat

NegroniはGoによるWeb ミドルウェアへの慣用的なアプローチです。 軽量で押し付けがましい作法は無く、またnet/httpハンドラの使用を推奨しています。

Martini の思想は気に入っているが、多くの魔法を含みすぎていると感じている方に、このNegroni はよく馴染むでしょう。

はじめに

Goをインストールし、GOPATHの設定を行った後、.goファイルを作りましょう。これをserver.goとします。

package main

import (
  "fmt"
  "net/http"

  "github.com/urfave/negroni"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintf(w, "Welcome to the home page!")
  })

  n := negroni.Classic() // Includes some default middlewares
  n.UseHandler(mux)

  http.ListenAndServe(":3000", n)
}

Negroni パッケージをインストールします (NOTE: >= go 1.1 以上のバージョンが必要です):

go get github.com/urfave/negroni

インストールが完了したら、サーバーを起動しましょう。

go run server.go

すると、Go標準パッケージの net/http によるWebサーバーがlocalhost:3000 で起動します。

Negroni はWeb Application Framework ですか?

Negroni はrevel やmartini のようなフレームワークではありません。 Negroniは net/httpと直接結びついて動作する、ミドルウェアにフォーカスされたライブラリです。

ルーティングの機能はありますか?

Negroni にルーティングの機能はありません。Goコミュニティには既に幾つかの優れたルーティングのライブラリが存在しており、Negroni はnet/httpと互換性のあるライブラリと協調して動作するように設計されています。例えば、Gorilla Muxと連携すると以下のようになります。

router := mux.NewRouter()
router.HandleFunc("/", HomeHandler)

n := negroni.New(Middleware1, Middleware2)
// Or use a middleware with the Use() function
n.Use(Middleware3)
// router goes last
n.UseHandler(router)

http.ListenAndServe(":3001", n)

negroni.Classic()

negroni.Classic() は、多くのアプリケーションで役に立つミドルウェアを提供します

これらはNegroni の便利な機能を利用し始めるのをとても簡単にしてくれます。

ハンドラ

Negroniは双方向のミドルウェアのフローを提供します。これは、negroni.Handler インターフェースを通じて行われます。

type Handler interface {
  ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
}

ミドルウェアが既にResponseWriter に書き込み処理を行っていない場合、次のミドルウェア・ハンドラを動かすために、チェーン内の次のhttp.HandlerFuncを呼び出す必要があります。

func MyMiddleware(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
  // 前処理
  next(rw, r)
  // 後処理
}

この時、MyMiddlewareUse 関数によってハンドラチェーンに割り当てることができます。

n := negroni.New()
n.Use(negroni.HandlerFunc(MyMiddleware))

また、標準パッケージに備わっているhttp.Handlerをハンドラチェーンに割り当てることもできます。

n := negroni.New()

mux := http.NewServeMux()
// ルーティングの処理

n.UseHandler(mux)

http.ListenAndServe(":3000", n)

Run()

Run はアドレスの文字列を受け取り、http.ListenAndServeと同様にサーバーを起動します。

package main

import (
  "github.com/urfave/negroni"
)

func main() {
  n := negroni.Classic()
  n.Run(":8080")
}

通常、net/http を使用し、ハンドラとしてNegroniを渡すことになります。 以下により柔軟性のあるサンプルを示します。

package main

import (
  "fmt"
  "log"
  "net/http"
  "time"

  "github.com/urfave/negroni"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintf(w, "Welcome to the home page!")
  })

  n := negroni.Classic()
  n.UseHandler(mux)

  s := &http.Server{
    Addr:           ":8080",
    Handler:        n,
    ReadTimeout:    10 * time.Second,
    WriteTimeout:   10 * time.Second,
    MaxHeaderBytes: 1 << 20,
  }
  log.Fatal(s.ListenAndServe())
}

Route Specific Middleware

あるルーティンググループにおいて、実行する必要のあるミドルウェアがある場合、 新しいNegroni のインスタンスを作成し、ルーティングハンドラとして使用することができます。

router := mux.NewRouter()
adminRoutes := mux.NewRouter()
// admin 関連のルーティングをココに記述

// admin のミドルウェアとして、Negroni インスタンスを作成
router.PathPrefix("/admin").Handler(negroni.New(
  Middleware1,
  Middleware2,
  negroni.Wrap(adminRoutes),
))

もしGorilla Muxを利用する場合、サブルーターを使うサンプルは以下の通りです。

router := mux.NewRouter()
subRouter := mux.NewRouter().PathPrefix("/subpath").Subrouter().StrictSlash(true)
subRouter.HandleFunc("/", someSubpathHandler) // "/subpath/"
subRouter.HandleFunc("/:id", someSubpathHandler) // "/subpath/:id"

// "/subpath" is necessary to ensure the subRouter and main router linkup
router.PathPrefix("/subpath").Handler(negroni.New(
  Middleware1,
  Middleware2,
  negroni.Wrap(subRouter),
))

Bundled Middleware

Static

このミドルウェアは、ファイルシステム上のファイルをサーバーからクライアントに送信します。もし指定されたファイルが存在しない場合、次のミドルウェアにリクエストの処理を依頼します。存在しないファイルへのアクセスに対して404 Not Foundを返したい場合、 http.FileServer をハンドラとして利用すべきです。

Example:

package main

import (
  "fmt"
  "net/http"

  "github.com/urfave/negroni"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintf(w, "Welcome to the home page!")
  })

  // Example of using a http.FileServer if you want "server-like" rather than "middleware" behavior
  // mux.Handle("/public", http.FileServer(http.Dir("/home/public")))

  n := negroni.New()
  n.Use(negroni.NewStatic(http.Dir("/tmp")))
  n.UseHandler(mux)

  http.ListenAndServe(":3002", n)
}

まず、/tmp ディレクトリからファイルをクライアントに送ろうとしますが、指定されたファイルがファイルシステム上に存在しない場合、プロキシは次のハンドラを呼び出します。

Recovery

このミドルウェアは、panicを受け取ると、500 internal Server Error をレスポンスします。 もし他のミドルウェアが既に応答処理を行い、クライアントにHTTP レスポンスが帰っている場合、このミドルウェアは失敗します。

Example:

package main

import (
  "net/http"

  "github.com/urfave/negroni"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    panic("oh no")
  })

  n := negroni.New()
  n.Use(negroni.NewRecovery())
  n.UseHandler(mux)

  http.ListenAndServe(":3003", n)
}

上記のコードは、 500 Internal Server Error を各リクエストごとに返します。 また、スタックトレースをログに出力するだけでなく、PrintStack がtrue に設定されている場合、クライアントにスタックトレースを出力します。(デフォルトでtrue に設定されています。)

Logger

このミドルウェアは、送られてきた全てのリクエストとレスポンスを記録します。

Example:

package main

import (
  "fmt"
  "net/http"

  "github.com/urfave/negroni"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintf(w, "Welcome to the home page!")
  })

  n := negroni.New()
  n.Use(negroni.NewLogger())
  n.UseHandler(mux)

  http.ListenAndServe(":3004", n)
}

各リクエストごとに、以下のようなログが出力されます。

[negroni] Started GET /
[negroni] Completed 200 OK in 145.446µs

サードパーティ製のミドルウェア

Negroni と互換性のあるミドルウェアの一覧です。あなたが作ったミドルウェアをここに追加してもらっても構いません(PRを送って下さい)

注意: ここの一覧は古くなっている可能性があります。英語版のREADME.md を適宜参照して下さい。

ミドルウェア名 作者 概要
binding Matt Holt Data binding from HTTP requests into structs
cloudwatch Colin Steele AWS cloudwatch metrics middleware
cors Olivier Poitrey Cross Origin Resource Sharing (CORS) support
delay Jeff Martinez Add delays/latency to endpoints. Useful when testing effects of high latency
gorelic Jingwen Owen Ou New Relic agent for Go runtime
Graceful Tyler Bunnell Graceful HTTP Shutdown
gzip phyber GZIP response compression
JWT Middleware Auth0 Middleware checks for a JWT on the Authorization header on incoming requests and decodes it
logrus Dan Buch Logrus-based logger
oauth2 David Bochenski oAuth2 middleware
onthefly Alexander Rødseth Generate TinySVG, HTML and CSS on the fly
permissions2 Alexander Rødseth Cookies, users and permissions
prometheus Rene Zbinden Easily create metrics endpoint for the prometheus instrumentation tool
render Cory Jacobsen Render JSON, XML and HTML templates
RestGate Prasanga Siripala Secure authentication for REST API endpoints
secure Cory Jacobsen Middleware that implements a few quick security wins
sessions David Bochenski Session Management
stats Florent Messa Store information about your web application (response time, etc.)
VanGoH Taylor Wrobel Configurable AWS-Style HMAC authentication middleware
xrequestid Andrea Franz Middleware that assigns a random X-Request-Id header to each request

Examples

Alexander Rødseth created mooseware, a skeleton for writing a Negroni middleware handler.

Live code reload?

gin and fresh both live reload negroni apps.

Go や Negroni の初心者にオススメの参考資料(英語)

Negroni について

Negroni は他ならぬCode Gangstaによって異常なまでにデザインされた素晴らしいライブラリです。