Build web application with Golangの備忘録
概要
Goはどのようにしてweb作業を行うか · Build web application with Golang
astaxieさんのgitbookでわからなかったところをメモする
3章を見ていきます
理解が甘いところがあるので、間違ってたら突っ込んでください。
3.2章 簡単なwebサーバー
main関数内からです。
そもそものhttprequestの実装、http.HandleFunc()、http.ListenAndServe()メソッドをそれぞれ解説します。
httprequest
コメントアウトを消したものを以下に引用します。
type Request struct { Method string URL *url.URL Proto string // "HTTP/1.0" ProtoMajor int // 1 ProtoMinor int // 0 Header Header Body io.ReadCloser GetBody func() (io.ReadCloser, error) // Go 1.8 ContentLength int64 TransferEncoding []string Close bool Host string Form url.Values PostForm url.Values // Go 1.1 MultipartForm *multipart.Form Trailer Header RemoteAddr string RequestURI string TLS *tls.ConnectionState Cancel <-chan struct{} // Go 1.5 Response *Response // Go 1.7 }
Cか何かを触っていた時にhttpリクエストは構造体だ、という言葉をどこかで聞いた覚えがありますが、goのhttpリクエストは構造体みたいですね。
最近学んだことですが、そもhttpリクエストとはクライアント-サーバ間のやりとりのメッセージの一つです。リクエストとレスポンスがありますが、要り様なのはリクエストなので割愛します。深くはsocket通信など調べてみると具体的な形が分かると思います。
簡単な例としてchromeでctrl+shift+iなどでデベロッパーツール、Networkタブに切り替えて(読み込みのためreloadして)Nameから適当なファイルをクリックしたHeadersを見て、こんな感じかーとだけ思っておけば大丈夫です。status codeとか、そういうのが書いてあると思います。
httpリクエストは大まかに3つに分けられ、それぞれリクエストライン、ヘッダー、メッセージボディと呼びます。上からこの順番で並んでいます。
リクエストラインが構造体のMethod+Url+Protoで成り立ちます。(Protoはプロトタイプではなくて、プロトコルの"プロト"ですね。きっと)
GET (任意のURL) HTTP/1.1 がよくある例です
順当に見ればヘッダーなのですが一度割愛して、メッセージボディが"送りたい情報本体"になります。よくあるhtmlを送るならおそらくから始まるタグから中の文書全体までがメッセージボディです。細かく追記すると、分けて送るので、メッセージボディ一つに文書全体が入っているとは限りません。
最後にヘッダーが残り全てです。情報が様々入ってます。
http.HandleFunc
本題に移ります。main文の一行目http.HandleFuncでは与えられたハンドラをパターンに登録するらしいです。
ここから先はServeMuxを読まなきゃならないみたいなので撤退。とりあえず、自分で定義したハンドラはこの関数を通過させることによって安全に利用できるのかな(?)
第二引数のハンドラから次に、sayhelloNameに移ります。
sayhelloName
この関数ではハンドラーとして、返したい(表示したい)具体的な処理と内容を記述します。メッセージボディに投げるものをここでやっておくイメージですね。(ハンドラーっていう語は範囲が広くて難しい)
この関数でrequestにhttpリクエストが入っているはずです。ResponseWriterはtimeoutWriterで定義されており、エラーで使うので今は気にしないでおきましょう。
ParseFormではフォーム情報が取得されます。山ほどあるヘッダー情報の中から、フォームだけを取り出します。/?以降に入力した配列の形で一行目に表示されるものです。
urlの最後の/に続き?から配列名=値の組を&で繋いでURLに入力するとこの形式でフォームを送ったことになるみたいですね。
余談ですがおそらく、URL.Schemeはnet/urlの構造体変数でparseする関数を変えれば動くと思います。
後はfor-rangeでkey-value形式で表示をしているだけです。
試しに、例のurlの後に&okasi=tabetaiと入力するとkey:okasiにvalue:tabetaiが追加されると思います。
http.ListenAndServe
main文二行目のものですね。err変数に代入しているみたいですが、その名の通りlistenをよろしく処理してくれるみたいですね。コメントを読んでみると、srv.AddrにTCPのネットワークアドレスが入っているのでそれを利用するらしい。Serve関数まで読んで断念した。全体を読まないとだめね。
やっていること自体は、よしなにサーバを待ち状態に設定するというところで。
とても参考になった記事だった。
まとめ
bind、listen、accept、sendがListenAndServeに集約されている。
ルーティング設定とハンドラーの設定ををHandleFuncで行っている。
ハンドラーは実処理部(?)。やりたいことを記述する。
感想
曖昧なので完全理解したい。