goのhttpパッケージの一部を理解する

## 初めに
参考になる記事がたくさんあるので、まずリンクを貼る

https://journal.lampetty.net/entry/understanding-http-handler-in-go

https://qiita.com/immrshc/items/1d1c64d05f7e72e31a98

https://www.morelife.work/entry/2019/09/27/go-web-app-handler



## 目的
自分はあまり理解力が高くないので、記事を見るだけでは理解できなかったりする。
参考になる記事たちを見て、改めて自分の中で整理してこの記事でアウトプットすることで自分の理解を深める

下記サンプルコードをもとに理解を深める

https://dev.classmethod.jp/articles/go-sample-rest-api/#toc-11

```go:main.go
package main

import (
	"net/http"

	"github.com/koga456/sample-api/controller"
	"github.com/koga456/sample-api/model/repository"
)

var tr = repository.NewTodoRepository()
var tc = controller.NewTodoController(tr)
var ro = controller.NewRouter(tc)

func main() {

	server := http.Server{
		Addr: ":8080",
	}
	http.HandleFunc("/todos/", ro.HandleTodosRequest)
	server.ListenAndServe()
}
```

## コードリーディング

>server := http.Server{
		Addr: ":8080",
	}

server変数にhttpパッケージのServer型にAddrのみ指定して代入

>http.HandleFunc("/todos/", ro.HandleTodosRequest)

```go
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}
```

pattern（パス)とfunc(ResponseWriter, *Request)型のhandlerを引数にDefaultServeMuxのHandleFuncメソッドを実行している

```go
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux
```

DeualtServeMuxはServeMux型の変数。
要するにhttp.HandleFuncはServeMux型をレシーバにもつHandleFuncメソッドを実行している。

```go
// HandleFunc registers the handler function for the given pattern
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))
```
HandleFunc（httpパッケージのServeMux型をレシーバにもつHandleFuncメソッド)

ServeMux型をレシーバに持つメソッドであり、pattern(/todos/)にhandler関数を登録(httpパッケージのServeMux型をレシーバに持つHandleメソッドを呼び出し)する

<details><summary>serveMux型,muxEntry型</summary>
<div>

```go

type ServeMux struct {
	mu    sync.RWMutex
	m     map[string]muxEntry
	es    []muxEntry // slice of entries sorted from longest to shortest.
	hosts bool       // whether any patterns contain hostnames
}

type muxEntry struct {
	h       Handler
	pattern string
}

```

</div>
</details>

http.ServeMux.Handleは何をするのか
<details><summary>ソースコード</summary>
<div>

```go
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
	mux.mu.Lock()
	defer mux.mu.Unlock()

	if pattern == "" {
		panic("http: invalid pattern")
	}
	if handler == nil {
		panic("http: nil handler")
	}
	if _, exist := mux.m[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	if mux.m == nil {
		mux.m = make(map[string]muxEntry)
	}
	e := muxEntry{h: handler, pattern: pattern}
	mux.m[pattern] = e
	if pattern[len(pattern)-1] == '/' {
		mux.es = appendSorted(mux.es, e)
	}

	if pattern[0] != '/' {
		mux.hosts = true
	}
}

```
</div>

</details>

pattern(パス)に対応づけてmux[string]muxEntryとして登録している

`mux.Handle(pattern, HandlerFunc(handler))`

handler(func ResponseWriter, *Request)をHandlerFunc型に変換してから渡すことで
func (m *ServeMux) Handle(pattern string, handler Handler)のHandler型に納めている

<details><summary>HandlerFunc型,Handler型</summary>
<div>

```go
type HandlerFunc func(ResponseWriter, *Request)

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request)

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}
```

</div>
</details>

HandlerFunc型はServeHttpメソッドを実装していて、 Handlerはインターフェースであり、ServeHttpを実装していることが求められていることがわかる

上記HandlerFunc型に変換しているのはServeHttpを実装させるため、実装していればHandler Interfaceに収まる。

>server.ListenAndServe()

先ほど定義したserver変数のListenAndServeメソッドを実行している。

```go
// ListenAndServe listens on the TCP network address srv.Addr and then calls Serve to handle requests on incoming connections.
// Accepted connections are configured to enable TCP keep-alives.

func (srv *Server) ListenAndServe() error
```

server型　他にもたくさんあるけど、よく使う?ものだけ抜粋

```go
type Server struct {
	// Addr optionally specifies the TCP address for the server to listen on,
	// in the form "host:port". If empty, ":http" (port 80) is used.
	// The service names are defined in RFC 6335 and assigned by IANA.
	// See net.Dial for details of the address format.
	Addr string

	Handler Handler // handler to invoke, http.DefaultServeMux if nil
}
```

今回、server型のAddrのみ指定して、Handlerは指定しなかったため、http.DefaultServeMuxになる

DefaultServeMuxについては上に書いたとおり、HandleFuncが呼び出されていく

## まとめ • 感想

今回色々な記事を見て頭に入らなかった原因がこの記事を書いている内にわかった

- 公式のdocを全然見てなかった

　　下記に理由はあるが、公式のドキュメントを読んでいなかった

- メソッドについての理解が足りていなかった

　　A Tour of Goをさらっと流し読みして、分かった気になっていたが、メソッド関数と関数の違いを分かっていなかったのでドキュメントを見てもイマイチピンと来なかった

後は書いている内に理解が深まっていった(わかっていないところがわかるようになった)ので、いい記事を書こうとは思わず、誰が見るわけでもないと思って気軽に書いていきたい