add get recipes by category page handler
This commit is contained in:
parent
370c77ab38
commit
d0bb3001f4
|
@ -22,13 +22,13 @@ type Response struct {
|
||||||
Recipes []models.Recipe `json:"recipes"`
|
Recipes []models.Recipe `json:"recipes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecipeProvider interface {
|
type RecipesProvider interface {
|
||||||
GetRecipes(ctx context.Context, offset, limit int) ([]models.Recipe, error)
|
GetRecipes(ctx context.Context, offset, limit int) ([]models.Recipe, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getRecipesLimit int = 16
|
const getRecipesLimit int = 16
|
||||||
|
|
||||||
func New(log *slog.Logger, recipeProvider RecipeProvider) http.HandlerFunc {
|
func New(log *slog.Logger, recipesProvider RecipesProvider) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
const op = "http-server.handlers.recipes.New"
|
const op = "http-server.handlers.recipes.New"
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ func New(log *slog.Logger, recipeProvider RecipeProvider) http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// get from storage
|
// get from storage
|
||||||
recipes, err := recipeProvider.GetRecipes(r.Context(), getRecipesLimit*(int(req.Page)-1), getRecipesLimit)
|
recipes, err := recipesProvider.GetRecipes(r.Context(), getRecipesLimit*(int(req.Page)-1), getRecipesLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get recipes from storage", sl.Err(err))
|
log.Error("failed to get recipes from storage", sl.Err(err))
|
||||||
render.JSON(w, r, resp.Error("failed to get recipes"))
|
render.JSON(w, r, resp.Error("failed to get recipes"))
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package recipes_by_category
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
"recipes/internal/domain/models"
|
||||||
|
resp "recipes/internal/lib/api/response"
|
||||||
|
"recipes/internal/lib/logger/sl"
|
||||||
|
|
||||||
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
|
"github.com/go-chi/render"
|
||||||
|
"github.com/go-playground/validator/v10"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
Page uint `json:"page" validate:"required,gt=0"`
|
||||||
|
Category string `json:"category" validate:"required,containsany"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
resp.Response
|
||||||
|
Recipes []models.Recipe `json:"recipes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RecipesProvider interface {
|
||||||
|
GetRecipesByCategory(ctx context.Context, offset, limit int, category string) ([]models.Recipe, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRecipesLimit int = 16
|
||||||
|
|
||||||
|
func New(log *slog.Logger, recipesProvider RecipesProvider) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
const op = "http-server.handlers.recipesByCategory.New"
|
||||||
|
|
||||||
|
log = log.With(
|
||||||
|
slog.String("op", op),
|
||||||
|
slog.String("request_id", middleware.GetReqID(r.Context())),
|
||||||
|
)
|
||||||
|
|
||||||
|
var req Request
|
||||||
|
// decode request
|
||||||
|
err := render.DecodeJSON(r.Body, &req)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to decode request body", sl.Err(err))
|
||||||
|
render.JSON(w, r, resp.Error("failed to decode request"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Debug("request body decoded", slog.Any("request", req))
|
||||||
|
// validate request
|
||||||
|
if err := validator.New().Struct(req); err != nil {
|
||||||
|
validateErr := err.(validator.ValidationErrors)
|
||||||
|
|
||||||
|
log.Error("invalid request", sl.Err(err))
|
||||||
|
render.JSON(w, r, resp.ValidationError(validateErr))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// get recipes from storage
|
||||||
|
recipes, err := recipesProvider.GetRecipesByCategory(r.Context(), getRecipesLimit*(int(req.Page)-1), getRecipesLimit, req.Category)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to get recipes from storage", sl.Err(err))
|
||||||
|
render.JSON(w, r, resp.Error("failed to get recipes"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// return
|
||||||
|
// return
|
||||||
|
render.JSON(w, r, Response{
|
||||||
|
Response: resp.OK(),
|
||||||
|
Recipes: recipes,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue