package api import ( "context" "git.brettb.xyz/goinv/server/internal/types" "github.com/go-chi/chi/v5" "github.com/go-chi/render" "net/http" "strconv" ) func (s *APIServer) setupCategoryRoutes() func(chi.Router) { return func(r chi.Router) { r.Get("/", makeHandler(s.getCategories)) r.Post("/", makeHandler(s.createCategory)) r.Route("/{categoryID}", func(r chi.Router) { r.Use(s.CategoryCtx) r.Get("/", makeHandler(s.getCategory)) r.Delete("/", makeHandler(s.deleteCategory)) }) } } func (s *APIServer) CategoryCtx(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { categoryIdStr := chi.URLParam(r, "categoryID") categoryId, err := strconv.ParseUint(categoryIdStr, 10, 64) if err != nil { render.Render(w, r, errNotFound) return } shelf, err := s.db.GetCategoryByID(categoryId) if err != nil { render.Render(w, r, errNotFound) return } ctx := context.WithValue(r.Context(), "category", shelf) next.ServeHTTP(w, r.WithContext(ctx)) }) } func (s *APIServer) getCategories(w http.ResponseWriter, r *http.Request) error { categories, err := s.db.GetCategories(0, 10) if err != nil { return err } total, err := s.db.TotalCategories() if err != nil { return err } return render.Render(w, r, &types.MultipleCategoryResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, Categories: categories, Total: total, }) } func (s *APIServer) getCategory(w http.ResponseWriter, r *http.Request) error { ctx := r.Context() category, ok := ctx.Value("category").(*types.Category) if !ok { return render.Render(w, r, errUnprocessable) } return render.Render(w, r, &types.CategoryResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, Category: category, }) } func (s *APIServer) deleteCategory(w http.ResponseWriter, r *http.Request) error { ctx := r.Context() category, ok := ctx.Value("category").(*types.Category) if !ok { return render.Render(w, r, errUnprocessable) } if ok, _ := s.db.DeleteCategoryByID(category.ID); !ok { return render.Render(w, r, errUnprocessable) } return render.Render(w, r, &types.CategoryResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, Category: category, }) } func (s *APIServer) createCategory(w http.ResponseWriter, r *http.Request) error { data := &types.CreateCategoryRequest{} if err := render.Bind(r, data); err != nil { return render.Render(w, r, errBadRequest(err)) } category := &types.Category{ Name: data.Name, } err := s.db.CreateCategory(category) if err != nil { return err } return render.Render(w, r, &types.CategoryResponse{ Response: &types.Response{ HTTPStatusCode: http.StatusOK, }, Category: category, }) }