ハンドラ関数
リクエストから読み取る
前のレッスンでは応答を書くだけでした。今度は届いたリクエストの中身を見ます。
Go
func handler(w http.ResponseWriter, r *http.Request) {
r.Method // "GET" や "POST"
r.URL.Path // "/items"
r.URL.Query() // クエリパラメータ
}メソッドで分ける
同じパスでも、メソッドが違えば別の操作です。
Go
func itemsHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
w.WriteHeader(405)
w.Write([]byte("method not allowed"))
return
}
// GET のときの処理
}405 は「そのメソッドは受け付けていません」という意味です。404(そんなパスは無い)とは違います。パスはあるがメソッドが違うときに使います。
条件に合わないものを先に弾いて return する形は、第3章の continue と同じ考え方です。本筋の処理が右に寄りません。
メソッド名は定数がある
Go
if r.Method != http.MethodGet {"GET" と直接書いても動きますが、http.MethodGet という定数が用意されています。綴りを間違えてもコンパイル時に気づけるのが利点です。第2章で iota の定数を作ったときと同じ理由です。
クエリパラメータを読む
プレーンテキスト
GET /items?keyword=きのこ&limit=10Go
q := r.URL.Query()
keyword := q.Get("keyword") // "きのこ"
limit := q.Get("limit") // "10"。文字列であることに注意Get は、無いときは空文字を返します。エラーにはなりません。
Go
keyword := q.Get("nothing") // ""第5章のマップと同じで、ゼロ値が返ってきます。「指定が無い」と「空文字を指定した」を区別したいなら、別の方法が要ります。入門では空文字を「指定なし」として扱えば十分です。
数値が欲しいときは、自分で変換します。
Go
import "strconv"
n, err := strconv.Atoi(q.Get("limit"))
if err != nil {
n = 10 // 変換できなければ既定値
}Atoi は文字列を整数にする関数です。第4章でやった (値, error) の形をしています。変換できないときにエラーが返るので、既定値に倒すか 400 を返すかを選べます。
要件
- メソッドが GET 以外なら 405 と
method not allowedを返す - GET なら
検索語: キーワードを返す - キーワードが空なら
検索語: なしを返す WriteHeaderは本文を書く前に呼ぶ
入出力例
callSearch("GET", "keyword=kinoko") → "200 検索語: kinoko"
callSearch("GET", "") → "200 検索語: なし"
callSearch("POST", "") → "405 method not allowed"
callSearch("DELETE", "keyword=x") → "405 method not allowed"ヒント
編集 ゆめさく編集部