2014年7月18日金曜日

Golang Cafe #38を開催しました。

Golang Cafe #38を開催しました。今回からGoのフレームワークを触ってみるというテーマにするということにしました。最初はgorilla toolkitを使ってみようということで、今回は、gorilla/muxを使いました。

gorilla/muxは主にURLからのroutingをサポートします。標準パッケージ(net/http)と同じように使えるので、薄いラッパーのようにも見えますが、強力な機能を持っているようなので、実際に自分のアプリケーションに利用してみようと思っています。

gorillaの使い方ですが、まず、Handlerを登録しておきます。

 r := mux.NewRouter()

 // RouterにHandlerを登録する。
 // 正規表現に一致しないURLは全て404になる。
 // 末尾に"/"をつけると、付けないと404になる。
 // Host()を使うとアクセス制限ができる。
 r.HandleFunc("/", IndexHandler).Host("www.sample.com")
 r.HandleFunc("/articles/{category}/", ArticleHandler).Methods("POST")
 r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

 r.NotFoundHandler = http.HandlerFunc(NotFound)

 log.Fatal(http.ListenAndServe(":8080", r))

ここで、http.HandleFunc()を使うのではなく、mux.NewRouter()を呼び出した戻り値のRouter#HandleFunc()を呼び出すのがポイントになります。
muxパッケージを介することで、gorilla toolkitでHandlerを認識することができるようになります。

引数は、http.HandleFunc()と同じなので省略しますが、指定するパスは拡張されていて、正規表現を入れることもできますし、{}で囲んでキーを指定することで、プログラムから指定されたパスの値を取得する事ができるようになります。

コメントにもありますが、Handlerに登録されていないパスのリクエストは全て404が返されます。
(これについては、私は400を返すものと思っていたので404を返す方が良いというのを聞いて新しい発見でした。400だと、存在している事を教えてしまうから、攻撃対象になるということでした。)

最後に、mux.Routerをhttp.ListenAndServe()の引数に指定することで、Routingの設定は完了です。
(GAE/Goだと、http.Handle()の引数に指定すれば同じように反映させる事ができます)

Routing時に登録したキーを取得するためには、mux.Vars()を呼び出します。
戻り値には、map[string] stringが返ってくるので、文字として扱えばPath内にある、キーの値を取得する事ができます。

次に挑戦したのが、NotFoundを返す時にログを出力するというのができるかどうかを試してみました。NotFoundを返すのは良いのですが、アクセスログぐらいは残せた方が便利だという理由からです。

方法は、ソースコードのr.NotFoundHandlerのHandlerを上書きすることで可能になるようです。ただし、上書きしたHandlerの中で、NotFoundのレスポンスを返すように処理を記述しなければいけません。

次回は、gorilla toolkitのcontextとsessionsを見る予定です。