package main import ( "encoding/json" "net/http" "github.com/gorilla/mux" "github.com/gosimple/slug" "github.com/xNok/go-rest-demo/pkg/recipes" ) func main() { // create the Store and Recipe Handler store := recipes.NewMemStore() recipesHandler := NewRecipesHandler(store) home := homeHandler{} router := mux.NewRouter() router.HandleFunc("/", home.ServeHTTP) router.HandleFunc("/recipes", recipesHandler.ListRecipes).Methods("GET") router.HandleFunc("/recipes", recipesHandler.CreateRecipe).Methods("POST") router.HandleFunc("/recipes/{id}", recipesHandler.GetRecipe).Methods("GET") router.HandleFunc("/recipes/{id}", recipesHandler.UpdateRecipe).Methods("PUT") router.HandleFunc("/recipes/{id}", recipesHandler.DeleteRecipe).Methods("DELETE") http.ListenAndServe(":8010", router) } func InternalServerErrorHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("500 Internal Server Error")) } func NotFoundHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) w.Write([]byte("404 Not Found")) } type RecipesHandler struct { store recipeStore } func NewRecipesHandler(s recipeStore) *RecipesHandler { return &RecipesHandler{ store: s, } } type recipeStore interface { Add(name string, recipe recipes.Recipe) error Get(name string) (recipes.Recipe, error) List() (map[string]recipes.Recipe, error) Update(name string, recipe recipes.Recipe) error Remove(name string) error } func (h *RecipesHandler) CreateRecipe(w http.ResponseWriter, r *http.Request) { // Recipe object that will be populated from json payload var recipe recipes.Recipe if err := json.NewDecoder(r.Body).Decode(&recipe); err != nil { InternalServerErrorHandler(w, r) return } resourceID := slug.Make(recipe.Name) if err := h.store.Add(resourceID, recipe); err != nil { InternalServerErrorHandler(w, r) return } w.WriteHeader(http.StatusOK) } func (h *RecipesHandler) ListRecipes(w http.ResponseWriter, r *http.Request) { recipes, err := h.store.List() jsonBytes, err := json.Marshal(recipes) if err != nil { InternalServerErrorHandler(w, r) return } w.WriteHeader(http.StatusOK) w.Write(jsonBytes) } func (h *RecipesHandler) GetRecipe(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] recipe, err := h.store.Get(id) if err != nil { if err == recipes.NotFoundErr { NotFoundHandler(w, r) return } InternalServerErrorHandler(w, r) return } jsonBytes, err := json.Marshal(recipe) if err != nil { InternalServerErrorHandler(w, r) return } w.WriteHeader(http.StatusOK) w.Write(jsonBytes) } func (h *RecipesHandler) UpdateRecipe(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] // Recipe object that will be populated from json payload var recipe recipes.Recipe if err := json.NewDecoder(r.Body).Decode(&recipe); err != nil { InternalServerErrorHandler(w, r) return } if err := h.store.Update(id, recipe); err != nil { if err == recipes.NotFoundErr { NotFoundHandler(w, r) return } InternalServerErrorHandler(w, r) return } jsonBytes, err := json.Marshal(recipe) if err != nil { InternalServerErrorHandler(w, r) return } w.WriteHeader(http.StatusOK) w.Write(jsonBytes) } func (h *RecipesHandler) DeleteRecipe(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] if err := h.store.Remove(id); err != nil { InternalServerErrorHandler(w, r) return } w.WriteHeader(http.StatusOK) } type homeHandler struct{} func (h *homeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Write([]byte("This is my home page")) }