Go Web Examplesの和訳 Routing (using gorilla/mux)

[Go勉強会 Webアプリケーション編 #1](https://go-golang.connpass.com/event/98075/)で使おうと思っている[Go Web Examples](https://gowebexamples.com/routes-using-gorilla-mux/)の和訳です。ほぼGoogle翻訳ですが、リンク等も整理された状態であると便利だと思い作りました。[前回（HTTP Server）](https://qiita.com/tikidunpon/items/f06e48c642d46fda4df7)、[次回: Go Web Examplesの和訳 （Templates）](https://qiita.com/tikidunpon/items/ed0486b5b54fa34c75c3)。

# はじめに

Goの[net/http](https://golang.org/pkg/net/http)パッケージは、HTTPプロトコルに多くの機能を提供します。それがうまく行かないことの1つは、リクエストURLを単一のパラメータに分割するような複雑なリクエストルーティングです。幸運なことに、これには非常に一般的なパッケージがあります。これは、Goコミュニティの優れたコード品質でよく知られています。この例では、[gorilla/mux](https://github.com/gorilla/mux)パッケージを使用して、名前付きパラメータ、GET/POSTハンドラ、およびドメイン制限を使用してルートを作成する方法を示します。

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

gorilla/muxは、GoのデフォルトのHTTPルーターに適合するパッケージです。 Webアプリケーションを書くときに生産性を向上させるための多くの機能が付属しています。また、Goのデフォルトのリクエストハンドラシグネチャ`func（w http.ResponseWriter、r * http.Request）`にも準拠しているため、ミドルウェアや既存のアプリケーションなどの他のHTTPライブラリとパッケージを混在させることができます。 GitHubからパッケージをインストールするには、`go get`コマンドを使用します（-uオプションは常に最新のバージョンをネットワークから取得します。）

```sh
go get -u github.com/gorilla/mux
```

# 新しいルーターの作成  

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

```go
r := mux.NewRouter()
```
# リクエストハンドラの登録
新しいルータを取得したら、いつものようにリクエストハンドラを登録できます。唯一の違いは、`http.HandleFunc（...）`を呼び出す代わりに、ルータで`HandleFunc`を以下のように呼び出すことです：`r.HandleFunc（...）`。


# URLパラメータ

[gorilla/mux](https://github.com/gorilla/mux)のルーターの最大の強みはリクエストURLからのセグメントの抽出です。
例えば、これはアプリケーションのURLです。

```go 
/books/go-programming-blueprint/page/10
```

このURLには2つの動的なセグメントがあります。

1. 書籍タイトルのスラッグ（go-programming-blueprint） 
2. ページ番号（10）

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

```go
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）が付属しています。

```go
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パッケージのデフォルトルータ（DefaultServeMux）を使用することを意味します。 独自のルータを使用するには、`nil`をルータの変数`r`で置き換えます。

```go
http.ListenAndServe(":80", r)
```


# コード（コピペ用）

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

```go
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メソッドに制限する。  

```go
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")
```

## Hostnames & Subdomains

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

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

## Schemes

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

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

## Path Prefixes & Subrouters

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

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

# 参考  
- [golang gorilla/mux vs chi](https://qiita.com/tikidunpon/items/c101421a5c122083e3cd)
- [次回: Go Web Examplesの和訳 （Templates）](https://qiita.com/tikidunpon/items/ed0486b5b54fa34c75c3)