132 lines
3.0 KiB
Go
132 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gosimple/slug"
|
|
"github.com/xNok/go-rest-demo/pkg/recipes"
|
|
)
|
|
|
|
func main() {
|
|
// Create Gin router
|
|
router := gin.Default()
|
|
|
|
// Instantiate recipe Handler and provide a data store
|
|
store := recipes.NewMemStore()
|
|
recipesHandler := NewRecipesHandler(store)
|
|
|
|
// Register Routes
|
|
router.GET("/", homePage)
|
|
router.GET("/recipes", recipesHandler.ListRecipes)
|
|
router.POST("/recipes", recipesHandler.CreateRecipe)
|
|
router.GET("/recipes/:id", recipesHandler.GetRecipe)
|
|
router.PUT("/recipes/:id", recipesHandler.UpdateRecipe)
|
|
router.DELETE("/recipes/:id", recipesHandler.DeleteRecipe)
|
|
|
|
// Start the server
|
|
router.Run()
|
|
}
|
|
|
|
func homePage(c *gin.Context) {
|
|
c.String(http.StatusOK, "This is my home page")
|
|
}
|
|
|
|
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(c *gin.Context) {
|
|
// Get request body and convert it to recipes.Recipe
|
|
var recipe recipes.Recipe
|
|
if err := c.ShouldBindJSON(&recipe); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// create a url friendly name
|
|
id := slug.Make(recipe.Name)
|
|
|
|
// add to the store
|
|
h.store.Add(id, recipe)
|
|
|
|
// return success payload
|
|
c.JSON(http.StatusOK, gin.H{"status": "success"})
|
|
}
|
|
|
|
func (h RecipesHandler) ListRecipes(c *gin.Context) {
|
|
r, err := h.store.List()
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
}
|
|
|
|
c.JSON(200, r)
|
|
}
|
|
|
|
func (h RecipesHandler) GetRecipe(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
recipe, err := h.store.Get(id)
|
|
if err != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
|
}
|
|
|
|
c.JSON(200, recipe)
|
|
}
|
|
|
|
func (h RecipesHandler) UpdateRecipe(c *gin.Context) {
|
|
// Get request body and convert it to recipes.Recipe
|
|
var recipe recipes.Recipe
|
|
if err := c.ShouldBindJSON(&recipe); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
id := c.Param("id")
|
|
|
|
err := h.store.Update(id, recipe)
|
|
if err != nil {
|
|
if err == recipes.NotFoundErr {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// return success payload
|
|
c.JSON(http.StatusOK, gin.H{"status": "success"})
|
|
}
|
|
|
|
func (h RecipesHandler) DeleteRecipe(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
err := h.store.Remove(id)
|
|
if err != nil {
|
|
if err == recipes.NotFoundErr {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// return success payload
|
|
c.JSON(http.StatusOK, gin.H{"status": "success"})
|
|
|
|
}
|