Goのnet/httpパッケージ周りについて最低限覚えておきたいポイント


#動機
Goのnet/httpパッケージについて、なんとなく雰囲気を理解していた程度だったので、まずは最低限を覚えておきたいポイントをまとめる趣旨で、あれこれ調べたことをまとめてみた。

#net/httpパッケージ
Goが標準で用意している、HTTPクライアント/サーバー機能を提供するパッケージです。

一方、巷では[beego](https://github.com/astaxie/beego)や[gin](https://github.com/gin-gonic/gin)といったサードパーティ製の人気フレームワークが乱立していて、デファクトスタンダートは決まっていない模様。
何れにせよ、フレームワークを使うと何が嬉しいのか知りたいので、この次のステップとして使ってみたいところです。


#HTTPサーバーの起動

周知の通り、Goでは[net/httpパッケージ](https://golang.org/pkg/net/http/#FileServer)を使えば簡単なHTTPサーバーを起動させることが出来ます。

環境構築を除けば、下記の通りわずか数行程度で済むので、手間の観点だけで見ればApachやNginxよりもリーズナブルな気がします。
なので、簡単なAPIサーバーを作る時に便利かもしれないです。（個人的見解）

```go:main.go
package main

import (
"fmt"
"net/http"
)

func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello World!")
}
```

コードを書いて`goコマンド`で実行してあげればサーバーが起動します。

```
go run main go
```

起動したら、ブラウザから`http://localhost:8080`にアクセスして、Hello World!と表示されていればOKです。


#動作確認
サーバー起動後、今度は`curlコマンド`でアクセスしてみると、こんな感じのレスポンスが帰って来ます。
このように、確りとサーバーとして動作していることを確認することもできます。

```
$ curl -vvv localhost:8080
* Rebuilt URL to: localhost:8080/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Wed, 01 May 2019 00:40:58 GMT
< Content-Length: 14
< Content-Type: text/plain; charset=utf-8
< 
Hello, world.
* Connection #0 to host localhost left intact
```

#net/httpのキホン

Goでサーバーを起動する際、肝になるポイントは次の2つになります。

- Handler
- Listen

#Handler
Handlerとは、何らかのアクションをトリガーに実行される関数のことです。
ここでは、HTTPリクエストに対するレスポンスを実行するためのHandlerを意味します。

###Handler作成

まず、HTTPリクエストを受け取った時にレスポンスを実行するHandlerを作ります。

```go
func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello World!")
}
```

`func handler`（handlerは関数名）は、第一引数に`http.ResponseWriter型`、`第二引数にhttp.Request型`を取ります。

ResponseWriter型はレスポンスを指定することが可能で、上記ではHello World！を出力する（wに入る文字列がブラウザで表示される）処理をレスポンスに指定しています。

このパターンはお作法みたいなものなので、覚えておきましょう。

###Handler登録
作ったHandlerは、net/httpパッケージが用意している`http.HandleFunc関数`で登録します。

```go
http.HandleFunc("/", handler)
```

第一引数にパス（URLパターン）を、第二引数にHandlerを定義することで、HTTPリクエストに対してレスポンスできるようになります。
上記の場合、パスを/で来たHTTPリクエストを返すhandler関数（＝Handler）をハンドラとして定義しています。


#Listen

Listenとは、サーバーのポートが開いている状態、つまりHTTPリクエストを受け付ける状態にあることを意味します。

###サーバー起動
Handlerの登録をしたら、net/httpパッケージが用意している`http.ListenAndServe関数`で、サーバーがHTTPリクエストを受け付けるようにします。

```go
http.ListenAndServe(":8080", nil)
```

第一引数に、ポート番号を表す文字列を渡し、第二引数にHandlerを渡すのが一般的のようです。
Handlerは、自分でHandlerとその処理を実装する場合を除き、通常はnilを使います。この場合、`DefaultServeMux`と呼ばれるデフォルトのHandlerが使用されます。

ServeMuxに関しては、[こちら](https://reiki4040.hatenablog.com/entry/2017/03/01/212647
)の記事の説明が分かりやすかったので抜粋。
>ServeMuxは、HTTPリクエストに対しての処理をPathごとに登録することができる構造体です。ServeMuxを使わなくても、HTTPリクエストを処理することはできますが、Pathごとの振り分けは余程のことがない限り必ず使うため、省略できるようになっています。


#まとめ

- GoでHTTPサーバーを起動するときのポイントは、HandlerとListenの2つ。
- サーバー起動の流れは、Handler作成 -> Handler登録 -> サーバー起動（Listen）の3ステップ。

今回は、net/httpパッケージを用いた簡単なHTTPサーバーの起動のみでしたが、自作のHandlerを実装したり、APIを返すモックサーバを作ってみたりと、色々調べながら手を動かしてステップアップして行きたい。

#参考

基本は全て公式ドキュメントに載っているので、ミニマム雰囲気だけでも掴んでおくのがベターだと思った。
https://golang.org/doc/articles/wiki/

あとは、Go言語に詳しいメルカリ上田氏の資料が参考になると思います。
https://www.slideshare.net/takuyaueda967/goweb-69949279