ルーティング (gorilla/mux使用)

こんにちは、Philippです!
私のプラットフォームであるGo Web Examples Coursesが公開されたことをお知らせします。GoでのWeb開発に関する分かりやすいビデオコースをお楽しみください。早期サポーター向けの特別オファーもご確認ください。
そちらでお会いしましょう! :)
詳細はこちら

はじめに

Goのnet/httpパッケージは、HTTPプロトコルのための多くの機能を提供します。しかし、リクエストURLを個々のパラメータに分割するような複雑なリクエストルーティングは得意ではありません。幸いなことに、Goコミュニティでコード品質の良さでよく知られている、このための非常に人気のあるパッケージがあります。この例では、gorilla/muxパッケージを使用して、名前付きパラメータ、GET/POSTハンドラ、ドメイン制限付きのルートを作成する方法を説明します。

gorilla/muxパッケージのインストール

gorilla/muxは、GoのデフォルトHTTPルータに適合するパッケージです。Webアプリケーションを作成する際の生産性を向上させるための多くの機能が備わっています。また、Goのデフォルトのリクエストハンドラシグネチャ`func (w http.ResponseWriter, r *http.Request)`にも準拠しているため、ミドルウェアや既存のアプリケーションなど、他のHTTPライブラリと組み合わせて使用できます。GitHubからパッケージをインストールするには、次のように`go get`コマンドを使用します。

go get -u github.com/gorilla/mux

新しいルータの作成

まず、新しいリクエストルータを作成します。ルータは、Webアプリケーションのメインルータであり、後でサーバーにパラメータとして渡されます。すべてのHTTP接続を受信し、登録するリクエストハンドラに渡します。次のように新しいルータを作成できます。

r := mux.NewRouter()

リクエストハンドラの登録

新しいルータを作成したら、通常のリクエストハンドラを登録できます。唯一の違いは、http.HandleFunc(...)を呼び出す代わりに、ルータでHandleFuncを次のように呼び出すことです:r.HandleFunc(...)

URLパラメータ

gorilla/muxルータの最大の強みは、リクエストURLからセグメントを抽出できることです。例として、これはアプリケーションのURLです。

/books/go-programming-blueprint/page/10
このURLには、2つの動的セグメントがあります。

  1. 書籍タイトルスラッグ (go-programming-blueprint)
  2. ページ (10)

上記のURLに一致するリクエストハンドラを作成するには、URLパターンの動的セグメントを次のようにプレースホルダーに置き換えます。

r.HandleFunc("/books/{title}/page/{page}", func(w http.ResponseWriter, r *http.Request) {
    // get the book
    // navigate to the page
})

最後は、これらのセグメントからデータを取得することです。パッケージには、http.Requestをパラメータとして受け取り、セグメントのマップを返す関数mux.Vars(r)が付属しています。

func(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    vars["title"] // the book title slug
    vars["page"] // the page
}

HTTPサーバーのルータの設定

http.ListenAndServe(":80", nil)の`nil`が何を意味するのか疑問に思ったことはありませんか?これは、HTTPサーバーのメインルータのパラメータです。デフォルトでは`nil`であり、これは`net/http`パッケージのデフォルトルータを使用することを意味します。独自のルータを使用するには、`nil`をルータ`r`の変数に置き換えます。

http.ListenAndServe(":80", r)

コード (コピー/ペースト用)

これは、この例で学んだことを試すために使用できる完全なコードです。

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/books/{title}/page/{page}", func(w http.ResponseWriter, r *http.Request) {
        vars := mux.Vars(r)
        title := vars["title"]
        page := vars["page"]

        fmt.Fprintf(w, "You've requested the book: %s on page %s\n", title, page)
    })

    http.ListenAndServe(":80", r)
}

gorilla/muxルータの機能

メソッド

リクエストハンドラを特定のHTTPメソッドに制限します。

r.HandleFunc("/books/{title}", CreateBook).Methods("POST")
r.HandleFunc("/books/{title}", ReadBook).Methods("GET")
r.HandleFunc("/books/{title}", UpdateBook).Methods("PUT")
r.HandleFunc("/books/{title}", DeleteBook).Methods("DELETE")

ホスト名とサブドメイン

リクエストハンドラを特定のホスト名またはサブドメインに制限します。

r.HandleFunc("/books/{title}", BookHandler).Host("www.mybookstore.com")

スキーム

リクエストハンドラをhttp/httpsに制限します。

r.HandleFunc("/secure", SecureHandler).Schemes("https")
r.HandleFunc("/insecure", InsecureHandler).Schemes("http")

パスプレフィックスとサブルータ

リクエストハンドラを特定のパスプレフィックスに制限します。

bookrouter := r.PathPrefix("/books").Subrouter()
bookrouter.HandleFunc("/", AllBooks)
bookrouter.HandleFunc("/{title}", GetBook)