314
175

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Go 言語の http パッケージにある Handle とか Handler とか HandleFunc とか HandlerFunc とかよくわからないままとりあえずイディオムとして使ってたのでちゃんと理解したメモ

Last updated at Posted at 2016-09-05

はじめに

  • Go 言語では以下のような簡単なコードでウェブサーバーを立ち上げることができますが、正確に意味を理解しておらずイディオムとして使っていたので整理するために一回ちゃんと調べてみました。
package main

import (
  "fmt"
  "net/http"
)

func main() {
  http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello World")
  })

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

http.Handler とは

  • http.Handler とは ServeHTTP 関数を持つだけのインターフェイスで HTTP リクエストを受けてレスポンスを返すことを責務とします。
type Handler interface {
  ServeHTTP(ResponseWriter, *Request)
}

http.Handle とは

func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
  • http.Handle とは表示する URL と、URL に対応する http.HandlerDefaultServeMux に登録する関数です。
  • DefaultServeMux とはデフォルトで http.ServeMux 型の構造体で URL に対応した http.Handler を実行するいわゆるルーターです。
  • また DefaultServeMux はルーターであると同時に ServeHTTP 関数を持つ http.Handler です。
  • http.ListenAndServe の第二引数が nil の場合 DefaultServeMux が Handler として指定されます。自分が分かりづらかったのはここで http.ListenAndServe が Handler を受け取ったり gorilla/mux のようなルーターを受け取ったりしていたので混乱しました。全てが http.Handler なんだと理解できてからはすっきりしました。
  • 以下の 1 と 2 と 3 はだいたい同じ意味の処理になります。
type AnyHandler struct {}
func (a *AnyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
anyHandler := &AnyHandler{}

// 1
http.Handle("/any/", anyHandler)
http.ListenAndServe(":8080", nil)

// 2
mux := http.NewServeMux()
mux.Handle("/any/", anyHandler)
http.ListenAndServe(":8080", mux)

// 3
http.ListenAndServe(":8080", http.HandleFunc(func(w http.ResponseWriter, r *http.Request){
  if r.URL.Path == "/any/" {
    anyHandler.ServeHTTP(w, r)
  }
}))

http.HandlerFunc とは

  • func(ResponseWriter, *Request) の別名の型で ServeHTTP 関数を持つので、関数を定義して http.HandlerFunc にキャストするだけで構造体を宣言することなく http.Handler を用意することができます。
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
  f(w, r)
}

http.HandleFunc とは

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	DefaultServeMux.HandleFunc(pattern, handler)
}
  • URL と func(ResponseWriter, *Request) を渡して DefaultServeMux に登録する関数です。
  • 内部で func(ResponseWriter, *Request) から http.HandlerFunc へのキャストが行われています。

さいごに

  • 全部ドキュメントに載っていて読めってはなしなのでドキュメント大切。
314
175
0

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
314
175

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?