learning_go/go-code-samples/go-rest-demo/cmd/gin/main.go
2025-12-20 10:21:45 +03:00

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"})
}