かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Go プログラミング実践入門を読みながら Go での Web App「mux と Cookie」

Go 言語で Web アプリを作るときにもう一つ外したらいけなさそうなものとして Mux というのがあるみたい。 Multiplexer っていうのかな。

package main

import (
    "fmt"
    "net/http"
)

func handleRequest(w http.ResponseWriter, req *http.Request) {
    name, ok := req.URL.Query()["name"]
    if ok {
        w.Write([]byte(fmt.Sprintf("Hello %v.", name[0])))
    } else {
        w.Write([]byte("Hello unknown user"))
    }
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", handleRequest)

    http.ListenAndServe("localhost:8080", mux)
}

使うとこんな感じ。今まで http に対して直接やってたことを mux に対してやるイメージ。 世の中の Go 向けの Web フレームワークは mux をベースにしてるものもあるらしい。

Cookie

クッキーを使うには、http.Cookie を使う。http.Request から Cookie メソッドを呼ぶと引数に指定した名前の Cookie のポインタとエラーが返ってくる。クッキーの設定は http.SetCookie 関数を使う。http.ResponseWriter と *Cookie を渡す感じ。

挙動を見る感じ body への出力より前にクッキーは設定しないとダメみたい。

package main

import (
    "fmt"
    "net/http"
    "strconv"
)

func handleRequest(w http.ResponseWriter, req *http.Request) {
    count, err := req.Cookie("_counter")
    if err != nil {
        count = &http.Cookie{Name: "_counter", Value: "0", HttpOnly: true}
    }

    currentCount, err := strconv.ParseInt(count.Value, 0, 64)
    count.Value = strconv.Itoa(int(currentCount + 1))
    http.SetCookie(w, count)

    name, ok := req.URL.Query()["name"]
    if ok {
        w.Write([]byte(fmt.Sprintf("Hello %v. You have been visiting this site %v times.", name[0], count.Value)))
    } else {
        w.Write([]byte("Hello unknown user"))
    }

}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", handleRequest)

    http.ListenAndServe("localhost:8080", mux)
}

こうすると何回かアクセスするとカウントアップしていく。

f:id:okazuki:20181122161928p:plain