package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "strconv" "strings" "time" "github.com/go-chi/chi" ) //Go Best practices: https://github.com/golovers/effective-go type Item struct { ID int64 `json:"id"` Name string `json:"name"` ValueCents int64 `json:"valueCents"` PurchaseCostCents int64 `json:"purchasedCostCents"` Aquired time.Time `json:"aquired"` Description string `json:"description"` Notes string `json:"notes"` SoldForCents int64 `json:"soldForCents"` SoldTo string `json:"soldTo"` Quantity int64 `json:"quantity"` Category Category `json:"category"` Subcategory Subcategory `json:"subcategory"` } func main() { r := chi.NewRouter() r.Route("/categories", func(r chi.Router) { r.Get("/", getCategoriesHandler) }) r.Route("/category", func(r chi.Router) { r.Get("/{id:[0-9]+}", getCategoryHandler) r.Post("/", insertCategoryHandler) r.Delete("/{id:[0-9]+}", deleteCategoryHandler) }) r.Route("/subcategory", func(r chi.Router) { r.Post("/", insertSubcategoryHandler) r.Delete("/{id:[0-9]+}", deleteSubcategoryHandler) }) err := http.ListenAndServe(":8088", r) if err != nil { panic(err) } } func deleteSubcategoryHandler(w http.ResponseWriter, r *http.Request) { value, _ := strconv.ParseInt(chi.URLParam(r, "id"), 0, 64) if !deleteSubcategory(value) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(fmt.Sprintf("Failed to delete %d", value))) return } w.WriteHeader(http.StatusOK) } func getCategoryHandler(w http.ResponseWriter, r *http.Request) { value, _ := strconv.ParseInt(chi.URLParam(r, "id"), 0, 64) category, ok := getCategoryByID(value) if !ok { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("Failed to get category.")) 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 deleteCategoryHandler(w http.ResponseWriter, r *http.Request) { id := strings.TrimPrefix(r.URL.Path, "/category/") value, err := strconv.ParseInt(id, 0, 64) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } if !deleteCategory(value) { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(fmt.Sprintf("Failed to delete %d", value))) return } w.WriteHeader(http.StatusOK) } func getCategoriesHandler(w http.ResponseWriter, r *http.Request) { categories, ok := getAllCategories() if !ok { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("Failed to fetch a list of categories.")) return } jsonBytes, err := json.Marshal(categories) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("Failed to get a list of categories.")) return } w.WriteHeader(http.StatusOK) w.Write(jsonBytes) } func insertCategoryHandler(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', expected application/json", ct))) return } bodyBytes, err := ioutil.ReadAll(r.Body) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Failed to parse request body")) return } defer r.Body.Close() var category Category err = json.Unmarshal(bodyBytes, &category) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Failed to unmarshal JSON")) return } id, ok := insertNewCategory(category.Name, category.Subcategories) if !ok { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("Failed to create the new category.")) return } w.WriteHeader(http.StatusOK) w.Write([]byte(fmt.Sprintf("New Record: %d", id))) } func insertSubcategoryHandler(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', expected application/json", ct))) return } bodyBytes, err := ioutil.ReadAll(r.Body) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Failed to parse request body")) return } defer r.Body.Close() var subcategory Subcategory err = json.Unmarshal(bodyBytes, &subcategory) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte("Failed to unmarshal JSON")) return } id, ok := insertSubcategory(subcategory.Name, subcategory.CategoryId) if !ok { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("Failed to create the new subcategory.")) return } w.WriteHeader(http.StatusOK) w.Write([]byte(fmt.Sprintf("New Record: %d", id))) }