Goことはじめ(net/httpパッケージ)
http://gihyo.jp/dev/feature/01/go_4beginners/0004?page=3
より学んだことメモ。
hello worldを返すだけのhttpサーバ
package main import ( "fmt" "net/http" ) // // http.ResponseWriterがレスポンスデータ // *http.Requestはリクエストデータ // func IndexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "hello world") } func main() { // ルーティング設定 http.HandleFunc("/", IndexHandler) // ポートを割り当ててサーバ起動 http.ListenAndServe(":3000", nil) }
JSONをPOSTでうけてファイルに保存する
package main import ( "encoding/json" "fmt" "log" "net/http" "os" ) type Person struct { ID int `json:"id"` Name string `json:"name"` } // // http.ResponseWriterがレスポンスデータ // *http.Requestはリクエストデータ // func IndexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "hello world") } func PersonHandler(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() // 処理の最後にBodyを閉じる if r.Method == "POST" { // リクエストボディをJSONに変換 var person Person decoder := json.NewDecoder(r.Body) err := decoder.Decode(&person) if err != nil { // エラー処理 log.Fatal(err) } // ファイル名を {id}.txt とする filename := fmt.Sprintf("%d.txt", person.ID) file, err := os.Create(filename) // ファイルを生成 if err != nil { log.Fatal(err) } defer file.Close() // ファイルにNameを書き込む _, err = file.WriteString(person.Name) if err != nil { log.Fatal(err) } // レスポンスデータとしてステータスコード201を返す w.WriteHeader(http.StatusCreated) } } func main() { // ルーティング設定 http.HandleFunc("/", IndexHandler) http.HandleFunc("/persons", PersonHandler) // ポートを割り当ててサーバ起動 http.ListenAndServe(":3000", nil) }
GETでうけてtemplateを使ってHTMLを返す
package main import ( "encoding/json" "fmt" "log" "net/http" "os" "strconv" "html/template" "io/ioutil" ) type Person struct { ID int `json:"id"` Name string `json:"name"` } // テンプレートのコンパイル // Mustを使うとエラー時にパニックを起こす // var t, err := template.personFiles("index.html") var t = template.Must(template.ParseFiles("index.html")) // // http.ResponseWriterがレスポンスデータ // *http.Requestはリクエストデータ // func IndexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "hello world") } func PersonHandler(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() // 処理の最後にBodyを閉じる if r.Method == "POST" { // リクエストボディをJSONに変換 var person Person decoder := json.NewDecoder(r.Body) err := decoder.Decode(&person) if err != nil { // エラー処理 log.Fatal(err) } // ファイル名を {id}.txt とする filename := fmt.Sprintf("%d.txt", person.ID) file, err := os.Create(filename) // ファイルを生成 if err != nil { log.Fatal(err) } defer file.Close() // ファイルにNameを書き込む _, err = file.WriteString(person.Name) if err != nil { log.Fatal(err) } // レスポンスデータとしてステータスコード201を返す w.WriteHeader(http.StatusCreated) } else if r.Method == "GET" { // パラメータを取得 id, err := strconv.Atoi(r.URL.Query().Get("id")) if err != nil { log.Fatal(err) } filename := fmt.Sprintf("%d.txt", id) b, err := ioutil.ReadFile(filename) if err != nil { log.Fatal(err) } // personを生成 person := Person { ID: id, Name: string(b), } // レスポンスにエンコーディングしたHTMLを書き込む t.Execute(w, person) } } func main() { // ルーティング設定 http.HandleFunc("/", IndexHandler) http.HandleFunc("/persons", PersonHandler) // ポートを割り当ててサーバ起動 http.ListenAndServe(":3000", nil) }
データを埋め込むには{{ }}で値をくくり,その中に埋め込みたいプロパティを指定する。
<!DOCTYPE html> <title>person</title> <h1>{{ .ID }} : {{ .Name }}</h1>