REST API
host = "127.0.0.1" | |
port = "5432" | |
sslmode="disable" | |
dbname = "mydb" | |
user = "admin" | |
pass = "qwerty" |
package main | |
import ( | |
"database/sql" | |
) | |
func insert(name, phone string) (sql.Result, error) { | |
return db.Exec("INSERT INTO phonebook VALUES (default, $1, $2)", | |
name, phone) | |
} | |
func remove(id int) (sql.Result, error) { | |
return db.Exec("DELETE FROM phonebook WHERE id=$1", id) | |
} | |
func update(id int, name, phone string) (sql.Result, error) { | |
return db.Exec("UPDATE phonebook SET name = $1, phone = $2 WHERE id=$3", | |
name, phone, id) | |
} | |
func readOne(id int) (Record, error) { | |
var rec Record | |
row := db.QueryRow("SELECT * FROM phonebook WHERE id=$1 ORDER BY id", id) | |
return rec, row.Scan(&rec.Id, &rec.Name, &rec.Phone) | |
} | |
func read(str string) ([]Record, error) { | |
var rows *sql.Rows | |
var err error | |
if str != "" { | |
rows, err = db.Query("SELECT * FROM phonebook WHERE name LIKE $1 ORDER BY id", | |
"%"+str+"%") | |
} else { | |
rows, err = db.Query("SELECT * FROM phonebook ORDER BY id") | |
} | |
if err != nil { | |
return nil, err | |
} | |
defer rows.Close() | |
var rs = make([]Record, 0) | |
var rec Record | |
for rows.Next() { | |
if err = rows.Scan(&rec.Id, &rec.Name, &rec.Phone); err != nil { | |
return nil, err | |
} | |
rs = append(rs, rec) | |
} | |
if err = rows.Err(); err != nil { | |
return nil, err | |
} | |
return rs, nil | |
} |
package main | |
import ( | |
"database/sql" | |
"encoding/json" | |
"net/http" | |
"strconv" | |
"github.com/julienschmidt/httprouter" | |
) | |
type Record struct { | |
Id int `json:"id"` | |
Name string `json:"name"` | |
Phone string `json:"phone"` | |
} | |
func getID(w http.ResponseWriter, ps httprouter.Params) (int, bool) { | |
id, err := strconv.Atoi(ps.ByName("id")) | |
if err != nil { | |
w.WriteHeader(400) | |
return 0, false | |
} | |
return id, true | |
} | |
func getRecords(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { | |
var str string | |
if len(r.URL.RawQuery) > 0 { | |
str = r.URL.Query().Get("name") | |
if str == "" { | |
w.WriteHeader(400) | |
return | |
} | |
} | |
recs, err := read(str) | |
if err != nil { | |
w.WriteHeader(500) | |
return | |
} | |
w.Header().Set("Content-Type", "application/json; charset=utf-8") | |
if err = json.NewEncoder(w).Encode(recs); err != nil { | |
w.WriteHeader(500) | |
} | |
} | |
func getRecord(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { | |
id, ok := getID(w, ps) | |
if !ok { | |
return | |
} | |
rec, err := readOne(id) | |
if err != nil { | |
if err == sql.ErrNoRows { | |
w.WriteHeader(404) | |
return | |
} | |
w.WriteHeader(500) | |
return | |
} | |
w.Header().Set("Content-Type", "application/json; charset=utf-8") | |
if err = json.NewEncoder(w).Encode(rec); err != nil { | |
w.WriteHeader(500) | |
} | |
} | |
func addRecord(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { | |
var rec Record | |
err := json.NewDecoder(r.Body).Decode(&rec) | |
if err != nil || rec.Name == "" || rec.Phone == "" { | |
w.WriteHeader(400) | |
return | |
} | |
if _, err := insert(rec.Name, rec.Phone); err != nil { | |
w.WriteHeader(500) | |
return | |
} | |
w.WriteHeader(201) | |
} | |
func updateRecord(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { | |
id, ok := getID(w, ps) | |
if !ok { | |
return | |
} | |
var rec Record | |
err := json.NewDecoder(r.Body).Decode(&rec) | |
if err != nil || rec.Name == "" || rec.Phone == "" { | |
w.WriteHeader(400) | |
return | |
} | |
res, err := update(id, rec.Name, rec.Phone) | |
if err != nil { | |
w.WriteHeader(500) | |
return | |
} | |
n, _ := res.RowsAffected() | |
if n == 0 { | |
w.WriteHeader(404) | |
return | |
} | |
w.WriteHeader(204) | |
} | |
func deleteRecord(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { | |
id, ok := getID(w, ps) | |
if !ok { | |
return | |
} | |
if _, err := remove(id); err != nil { | |
w.WriteHeader(500) | |
} | |
w.WriteHeader(204) | |
} |
package main | |
import ( | |
"database/sql" | |
"fmt" | |
"log" | |
"net/http" | |
"os/user" | |
"github.com/FogCreek/mini" | |
"github.com/julienschmidt/httprouter" | |
_ "github.com/lib/pq" | |
) | |
func fatal(err error) { | |
if err != nil { | |
log.Fatal(err) | |
} | |
} | |
func params() string { | |
u, err := user.Current() | |
fatal(err) | |
cfg, err := mini.LoadConfiguration(u.HomeDir + "/.phonebookrc") | |
fatal(err) | |
info := fmt.Sprintf("host=%s port=%s dbname=%s "+ | |
"sslmode=%s user=%s password=%s ", | |
cfg.String("host", "127.0.0.1"), | |
cfg.String("port", "5432"), | |
cfg.String("dbname", u.Username), | |
cfg.String("sslmode", "disable"), | |
cfg.String("user", u.Username), | |
cfg.String("pass", ""), | |
) | |
return info | |
} | |
var db *sql.DB | |
func main() { | |
var err error | |
db, err = sql.Open("postgres", params()) | |
fatal(err) | |
defer db.Close() | |
_, err = db.Exec("CREATE TABLE IF NOT EXISTS " + | |
`phonebook("id" SERIAL PRIMARY KEY,` + | |
`"name" varchar(50), "phone" varchar(100))`) | |
fatal(err) | |
router := httprouter.New() | |
router.GET("/api/v1/records", getRecords) | |
router.GET("/api/v1/records/:id", getRecord) | |
router.POST("/api/v1/records", addRecord) | |
router.PUT("/api/v1/records/:id", updateRecord) | |
router.DELETE("/api/v1/records/:id", deleteRecord) | |
http.ListenAndServe(":8080", router) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment