前回はデータベースの操作方法を見てきました。
今回はWebサーバで受けた情報をデータベースに保存します。
POST でデータ保存
POSTで受けたリクエストボディの Json 文字列をデコードし、データベースにインサートしてみます。
func usersHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { decoder := json.NewDecoder(r.Body) var u User err := decoder.Decode(&u) if err != nil { panic(err) } db := h2.Db() defer db.Close() db.Exec("INSERT INTO users(name, email) VALUES($1, $2);", u.Name, u.Email) defer r.Body.Close() } }
前回までの内容を組み合わせただけです。
GET でデータ取得
GETリクエストで保存したデータをJsonで取得します。
func usersHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { db := h2.Db() defer db.Close() rows, err := db.Query(`select id, name, email from users`) if err != nil { log.Fatal(err) } defer rows.Close() users := []User{} for rows.Next() { var u User rows.Scan(&u.Id, &u.Name, &u.Email) users = append(users, u) } json, err := json.Marshal(users) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Write(json) } }
ユーザ型のスライスを []User{}
で作り、rows.Next()
でデータベースのレコードを取得しながら追加しています。
結果は Marshal してレスポンスに書き込んでいるだけです。
実行
POST で登録してみます。
GETで取得してみます。
登録されていますね。
まとめ
全体像は以下のようになりました。
package main import ( "log" "net/http" "encoding/json" "github.com/xxxxx/hello/h2" ) type User struct { Id int `json:"id"` Name string `json:"name"` Email string `json:"e-mail"` } func handler(w http.ResponseWriter, r *http.Request) { u := User{ Id : 1, Name : "Thome", Email : "thome@example.com"} json, err := json.Marshal(u) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Write(json) } func usersHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { db := h2.Db() defer db.Close() rows, err := db.Query(`select id, name, email from users`) if err != nil { log.Fatal(err) } defer rows.Close() users := []User{} for rows.Next() { var u User rows.Scan(&u.Id, &u.Name, &u.Email) users = append(users, u) } json, err := json.Marshal(users) if err != nil { log.Fatal(err) } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Write(json) } else if r.Method == "POST" { decoder := json.NewDecoder(r.Body) var u User err := decoder.Decode(&u) if err != nil { panic(err) } db := h2.Db() defer db.Close() db.Exec("INSERT INTO users(name, email) VALUES($1, $2);", u.Name, u.Email) defer r.Body.Close() } } func main() { h2.StartH2() h2.InitDb() http.HandleFunc("/", handler) http.HandleFunc("/users", usersHandler) err := http.ListenAndServe(":8080", nil) if err != nil { log.Fatal("Error ListenAndServe : ", err) } }
package h2 import ( "log" "os" "net/http" "io" "os/exec" "path/filepath" _ "github.com/lib/pq" "database/sql" "time" ) const ( url = "http://central.maven.org/maven2/com/h2database/h2/1.4.194/h2-1.4.194.jar" path = "lib/h2-1.4.194.jar" ) func download(url string, path string) error { out, err := os.Create(path) if err != nil { return err } defer out.Close() resp, err := http.Get(url) if err != nil { return err } defer resp.Body.Close() if _, err := io.Copy(out, resp.Body); err != nil { return err } return nil } func StartH2() { if _, err := os.Stat(path); os.IsNotExist(err) { os.MkdirAll(filepath.Dir(path), 0755) if err := download(url, path); err != nil { panic(err) } } cmd := exec.Command("java", "-cp", path, "org.h2.tools.Server") cmd.Start() time.Sleep(3 * time.Second) log.Printf("H2 Started. PID[%v]", cmd.Process.Pid) } func StopH2() { err := exec.Command("java", "-cp", path, "org.h2.tools.Server", "-tcpShutdown", "tcp://localhost:9092").Run() if err != nil { log.Fatal(err) } } func InitDb() { db := Db() defer db.Close() db.Exec(` CREATE TABLE users ( id INTEGER auto_increment PRIMARY KEY, name VARCHAR(20), email VARCHAR(255) ); `) } func Db() *sql.DB { db, err := sql.Open("postgres", "postgres://sa:pass@localhost:5435/~/testdb?sslmode=disable") if err != nil { panic(err) } return db }