From bb01c11859f5e413299452bd9f9b82c4d31ba8e2 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Wed, 8 Sep 2021 14:52:48 -0500 Subject: [PATCH] Added a more RESTful interface for the category enities. --- cmd/inv/main.go | 110 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 5 deletions(-) diff --git a/cmd/inv/main.go b/cmd/inv/main.go index 800ae56..dda7e23 100644 --- a/cmd/inv/main.go +++ b/cmd/inv/main.go @@ -6,6 +6,7 @@ import ( "fmt" "io/ioutil" "net/http" + "strconv" "time" _ "github.com/lib/pq" @@ -39,6 +40,7 @@ type Subcategory struct { func main() { http.HandleFunc("/categories", categories) + http.HandleFunc("/category", category) err := http.ListenAndServe(":8080", nil) if err != nil { @@ -51,14 +53,102 @@ func categories(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": getCategories(w, r) - case "POST": - insertCategory(w, r) default: w.WriteHeader(http.StatusMethodNotAllowed) w.Write([]byte("Method not allowed")) } } +func category(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case "GET": + getCategory(w, r) + case "POST": + insertCategory(w, r) + case "DELETE": + deleteCategory(w, r) + default: + w.WriteHeader(http.StatusMethodNotAllowed) + w.Write([]byte("Method not allowed")) + } +} + +func getCategory(w http.ResponseWriter, r *http.Request) { + id := r.URL.Query().Get("id") + + value, err := strconv.ParseInt(id, 0, 64) + + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + + psqlInfo := fmt.Sprintf("host=%s port=%d user=%s dbname=%s sslmode=disable", "localhost", 5432, "postgres", "inv") + db, err := sql.Open("postgres", psqlInfo) + + if err != nil { + panic(err) + } + + defer db.Close() + + var category Category + + if err := db.QueryRow("SELECT * FROM category WHERE category_id = $1;", value).Scan(&category.Id, &category.Name); err != nil { + if err == sql.ErrNoRows { + w.Write([]byte("No rows found")) + return + } + + w.Write([]byte(err.Error())) + return + } + + jsonBytes, err := json.Marshal(&category) + + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + w.WriteHeader(http.StatusOK) + w.Write(jsonBytes) +} + +func deleteCategory(w http.ResponseWriter, r *http.Request) { + id := r.URL.Query().Get("id") + + value, err := strconv.ParseInt(id, 0, 64) + + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + + psqlInfo := fmt.Sprintf("host=%s port=%d user=%s dbname=%s sslmode=disable", "localhost", 5432, "postgres", "inv") + db, err := sql.Open("postgres", psqlInfo) + + if err != nil { + panic(err) + } + + defer db.Close() + + _, err = db.Exec("DELETE FROM category WHERE category_id = $1;", value) + + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return + } + + w.WriteHeader(http.StatusOK) + w.Write([]byte(fmt.Sprintf("Deleted category '%d'.", value))) +} + func getCategories(w http.ResponseWriter, r *http.Request) { //Note: The postgres driver seems to get confused when no password is supplied, so omit it in the connection sting. //https://rajyavardhan.medium.com/when-you-get-relation-does-not-exist-in-postgres-7ffb0c3c674b @@ -104,6 +194,14 @@ func getCategories(w http.ResponseWriter, r *http.Request) { } func insertCategory(w http.ResponseWriter, r *http.Request) { + ct := r.Header.Get("content-type") + + if ct != "application/json" { + w.WriteHeader(http.StatusUnsupportedMediaType) + w.Write([]byte(fmt.Sprintf("Unsupported media type '%s'", ct))) + return + } + bodyBytes, err := ioutil.ReadAll(r.Body) if err != nil { @@ -112,6 +210,8 @@ func insertCategory(w http.ResponseWriter, r *http.Request) { return } + defer r.Body.Close() + var category Category err = json.Unmarshal(bodyBytes, &category) @@ -127,13 +227,13 @@ func insertCategory(w http.ResponseWriter, r *http.Request) { if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte("Failed to connect to the DB")) + w.Write([]byte(err.Error())) return } id := 0 - err = db.QueryRow("INSERT INTO category (category_name) VALUES ($1) RETURNING category_id", category.Name).Scan(&id) + err = db.QueryRow("INSERT INTO category (category_name) VALUES ($1) RETURNING category_id;", category.Name).Scan(&id) if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -142,5 +242,5 @@ func insertCategory(w http.ResponseWriter, r *http.Request) { } w.WriteHeader(http.StatusOK) - w.Write([]byte(fmt.Sprint("New Record: ", id))) + w.Write([]byte(fmt.Sprintf("New Record: %d", id))) }