net/http で学ぶ interface 

# 自己紹介
普段はインターン先では Python を使って ML を用いた ソフトウェアの開発をしていますが、エンジニアとして成長するために静的型付け言語を学ぼうと思いました。その第一歩に選ばれた Go を学んでいくにあたり、interface 周りでつまづき、色々調べる中で自分なりに腑に落ちたので共有させていただきます。

- [TL; DR](#tl-dr)
- [⭐️ interface とは](#️-interface-とは)
- [⭐️ http における紛らわしいやつらの違い](#️-http-における紛らわしいやつらの違い)
    - [Handler](#handler)
    - [HandlerFunc](#handlerfunc)
    - [Handle](#handle)
    - [HandlerFunc](#handlerfunc-1)
- [⭐️ 実際の関数の流れ](#️-実際の関数の流れ)
- [⭐️ 実装できるのは構造体だけじゃない](#️-実装できるのは構造体だけじゃない)
- [最後に](#最後に)
    - [参考](#参考)


# TL; DR

Golang における net/http モジュールのルーティングついての紹介です。
ルーティングするとき誤魔化していたところをしっかり公式や記事を読んだことで理解につながったので共有させていただきます。
結論から言うと http で interface を実装してくれているので何も考えずに

```Go
http.HandleFunc("/endpoint", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Hello World")
})
```

といったふうに書くことができます。

この記事を読んでわかることは、

- Go ってすごい
- interface の使われ方

などです。気楽に読んでいただければ嬉しいです 🙇‍♂️
<br><br>

# ⭐️ interface とは
Golang におけるインターフェースとは、簡単に言うと**メソッドの塊**のことです。
また、とある構造体などに対してインターフェースに定義されているメソッド全てを定義していることをと**インターフェースを実装**していると言います。
この時点で Python しか書いてこなかった僕の頭は ??? になりました。
実際のコードを見てみましょう。

```Go
type Animal interface {
	Eat()
    Sleep()
}

type Dog struct {}

func (d *Dog) Eat() {
	fmt.Println("mogumogu") // mogumogu と表示されます
}

func (d *Dog) Sleep() {
	fmt.Println("suyasuya")
}
```

序盤 4 行で interface Animal を定義しています。
Dog と言う構造体を定義し、Dog に対して Animal で宣言されているメソッドたちを定義します。この時点で、**Dog は Animal interface を実装した**ことになりました。
例えば、 `Cat` と言う名前の構造体を定義し、`Eat` と `Sleep` を定義することで Cat も Animal interface を自動的に実装したことになります。
<br><br>

# ⭐️ http における紛らわしいやつらの違い

http における紛らわしい奴等リストは

- Handler
- HandlerFunc
- Handle
- HandleFunc

です。
実際にそれぞれ net/http/server.go に実装されているので見ていきましょう。

### Handler

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

Handler は **interface** です。ただ 1 つ ServeHTTP と言う関数さえ実装してくれれば OK な interface です。

### HandlerFunc

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

HandlerFunc は**関数の型**です。ResponseWriter と \*Request を引数に取るような関数の型ですね。

### Handle

```go
func Handle(pattern string, handler Handler) {
	DefaultServeMux.Handle(pattern, handler)
}
```

Handle は**実際の関数**です。関数内部で何をやっているかについては長いので割愛させていただきます。簡単に言うと `pattern` エンドポイントに対して `handler` を紐付けています。(関数内部の `Handle` は外の `Handle` とは関係なく、`DefaultServeMux` のメソッドであることに注意してください。)

### HandlerFunc

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

HandlerFunc も**実際の関数**ですね。TL; DR ではこの関数を呼び出していました。

こちらは短いので内部の関数をみてみましょう。

```go
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    if handler == nil {
        panic("http: nil handler")
    }
    mux.Handle(pattern, HandlerFunc(handler))
}
```

最終行に全てが詰まっています。

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

つまり、

- `HandlerFunc` メソッドは `Handle` メソッドを呼び出していること
- `handler` (コールバック関数) を `HandlerFunc` でラップしていること

が肝になっているわけです。
これらによって、僕たちは何も考えずに TL; DR で書いたようなコードを書けるわけです。
<br><br>

## ⭐️ 実際の関数の流れ

これまでに勉強したことを実際の流れに即して見ていきましょう。きっと感動してしまうことでしょう。
まず、TL; DR で書いたように僕たちは

```go
http.HandleFunc("/endpoint", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Hello")
})
```

エンドポイントを実装する時はこう書くだけでよかったのです。
`HandleFunc`が呼ばれているので見てみましょう。

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

- pattern = “/endpoint”
- handler = func(w, r)

となっていて良さそうですね。
次に呼ばれているのは `DefaultServeMux.HandleFunc` です。

```go
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    if handler == nil {
        panic("http: nil handler")
    }
    mux.Handle(pattern, HandlerFunc(handler))
}
```

- pattern = “/endpoint”
- handler = func(w, r)

ここも良さそうですね。
次に呼ばれるのが `mux.Handle` です。
ここが大事なポイントです。(\*1)

```go
func (mux *ServeMux) Handle(pattern string, handler Handler) {
    // ルーティング
}
```
mux.Handle に関しては先ほど割愛させてもらったので引数だけ見ます。(関数としては実際にルーティングしている部分を担っています。)

- pattern = “/endpoint”
- handler = Handler(func(w, r))

1 つ前の メソッドで func(w, r) を `HandlerFunc` 型に**キャスト**していましたが、今回のメソッドの第 2 引数 `Handler` ではないです。。。なぜでしょう。。。
見返してみると、`Handler` は interface だったので、`HandlerFunc(f(w, r))` がどこかで Handler interface を実装してないといけません。つまり、`HandlerFunc` が `ServeHTTP` メソッドを定義していないといけないわけです。
僕たちはいちいち コールバック関数に `ServeHTTP` メソッドを実装していないのできっとパッケージ側で実装してくれているのだろうと踏んで見てみると
```go
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
	f(w, r)
}
```
2083 行目からありました！
つまり HandlerFunc は晴れて Handler interface に昇格して(\*1)のメソッドが通り、無事ルーティングできるわけです。
<br><br>

## ⭐️ 実装できるのは構造体だけじゃない

「⭐️ interface とは」で見たような超具体的な構造体に対して interface を実装することが多くあると思うのですが、Golang の標準モジュールでやっていたことは、
`HandlerFunc` と言う **関数の型** に対して interface を実装する
と言うより抽象化されたことでした。
これのおかげで、関数をキャストして、 HTTP サーバーのハンドラーとしてふるまうようにできたのです。(すごい 😭)
またすごいポイントとしては `ServeHTTP` はその処理内容をハンドラーに完全に委譲していたことです。これのおかげでハンドラーに柔軟性が出てよしななエンドポイントが作成できます。
interface のおかげで全く裏のことを知らずにエンドポイント作成できるのは非常にいいことですね

## 最後に

ここまで読んでくださった方、ありがとうございました。
何も考えずに実装できるのはいいことですが、やっぱ裏側がちょっと気になって、調べて腑に落ちると感動しますね。
何か間違えたことがあれば教えていただけると幸いです。

### 参考

[https://qiita.com/\_kyamasan/items/940e575bc77e6b1f8ddb](https://qiita.com/_kyamasan/items/940e575bc77e6b1f8ddb)
[https://pkg.go.dev/net/http](https://pkg.go.dev/net/http)