LoginSignup
7
0

More than 5 years have passed since last update.

Go Web Examplesの和訳(Middleware: Basic)

Last updated at Posted at 2018-12-09

Go勉強会 Webアプリケーション編 #3 でやろうと思っている Go Web Examples: Middleware (Basic)の和訳です。と言ってもほとんど解説文がないので訳するところもないのですけどねー

Middleware: Basic

この例では Go で簡単なロギングのミドルウェアを作る方法を示します。

ミドルウェアは単に http.HandlerFunc を引数の一つとして受け取り、それをラップし、サーバーが呼び出すための新しい httpHandlerFunc を返します。

// basic-middleware.go
package main

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

func logging(f http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Println(r.URL.Path)
        f(w, r)
    }
}

func foo(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "foo")
}

func bar(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "bar")
}

func main() {
    http.HandleFunc("/foo", logging(foo))
    http.HandleFunc("/bar", logging(bar))

    http.ListenAndServe(":8080", nil)
}
$ go run basic-middleware.go
2017/02/10 23:59:34 /foo
2017/02/10 23:59:35 /bar
2017/02/10 23:59:36 /foo?bar

$ curl -s http://localhost:8080/foo
$ curl -s http://localhost:8080/bar
$ curl -s http://localhost:8080/foo?bar

補足

駆け出し Gopher (私もですが)がこれを初見で理解するのはちょっときついと思います。

ミドルウェアとはなんでしょうか? Wikipedia によると

コンピュータの基本的な制御を行うオペレーティングシステム(OS)と、各業務処理を行うアプリケーションソフトウェアとの中間に入るソフトウェアのこと。

とありますが、ここで言っているのはそんなたいそうなもののことではなく、HTTP ハンドラコードの前後に差し込んでなんかちょっとやらせるためのコードのことです。

この例のコードでミドルウェアを使う前のコードは次のようになっていたはずです。

package main

import (
    "fmt"
    "net/http"
)

func foo(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "foo")
}

func bar(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "bar")
}

func main() {
    http.HandleFunc("/foo", foo)
    http.HandleFunc("/bar", bar)

    http.ListenAndServe(":8080", nil)
}

単純に foo/bar をレスポンスとして返すだけのものです。

そこに登場するのが次のミドルウェアです。

func logging(f http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Println(r.URL.Path)
        f(w, r)
    }
}

この http.HandlerFunc を受け取って新しい http.HanlderFunc を返す logging という関数がミドルウェアです。この関数はログを一行出力してから元々の http.HandlerFuncf を実行する関数を新しく作って返すものです。

この logging ともともとの foo を組み合わせて

http.HandleFunc("/foo", foo)

となっていたところを

http.HandleFunc("/foo", logging(foo))

を書き換えてやるとログを一行出力してから foo を呼び出す関数を作って http.HandleFunc に渡してやることができ、クライアントからリクエストがあるたびにログを出力して foo というレスポンスを返すことができます。

このようにしてログの出力処理を差し込むということをやっています。

7
0
1

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
7
0