160 lines
3.6 KiB
Go
160 lines
3.6 KiB
Go
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"))
|
|
}
|