diff --git a/service/meal/db/mealdb/client.go b/service/meal/db/mealdb/client.go index 2213b2da3cba4ba6a9fc32342bab577ec1ed01ba..0a3de13fec74e32585eb241a597b692164b087cc 100644 --- a/service/meal/db/mealdb/client.go +++ b/service/meal/db/mealdb/client.go @@ -3,6 +3,7 @@ package mealdb import ( "encoding/json" "errors" + "fmt" "net/http" "strconv" "time" @@ -26,24 +27,104 @@ func GetRandomMeal() (*model.Meal, error) { if err != nil { return nil, err } - if response.StatusCode != http.StatusOK { - return nil, errors.New("mealdb request failed") - } var mealResponse *MealResponse err = json.NewDecoder(response.Body).Decode(&mealResponse) if err != nil { return nil, err } - return getMeal(mealResponse) + + if len(mealResponse.Meals) < 1 { + return nil, errors.New("no meals within the response") + } + currentMeal := mealResponse.Meals[0] + + return createMeal(currentMeal) } -func getMeal(mealResponse *MealResponse) (*model.Meal, error) { - meal := &model.Meal{} +func GetMeal(id int) (*model.Meal, error) { + path := fmt.Sprintf("lookup.php?i=%d", id) + request, err := http.NewRequest(http.MethodGet, baseUrl+path, nil) + if err != nil { + return nil, err + } + response, err := client.Do(request) + if err != nil { + return nil, err + } + + var mealResponse *MealResponse + err = json.NewDecoder(response.Body).Decode(&mealResponse) + if err != nil { + return nil, err + } + if len(mealResponse.Meals) < 1 { return nil, errors.New("no meals within the response") } currentMeal := mealResponse.Meals[0] + + return createMeal(currentMeal) +} + +func SearchMealByName(name string) ([]*model.Meal, error) { + path := fmt.Sprintf("search.php?s=%s", name) + request, err := http.NewRequest(http.MethodGet, baseUrl+path, nil) + if err != nil { + return nil, err + } + response, err := client.Do(request) + if err != nil { + return nil, err + } + var mealResponse *MealResponse + err = json.NewDecoder(response.Body).Decode(&mealResponse) + if err != nil { + return nil, err + } + + meals := []*model.Meal{} + for _, v := range mealResponse.Meals { + meal, err := createMeal(v) + if err != nil { + continue + } + meals = append(meals, meal) + } + + return meals, nil +} + +func SearchMealBy(value string, filter model.Filter) ([]*model.MealOverview, error) { + path := fmt.Sprintf("filter.php?%s=%s", filter, value) + request, err := http.NewRequest(http.MethodGet, baseUrl+path, nil) + if err != nil { + return nil, err + } + response, err := client.Do(request) + if err != nil { + return nil, err + } + var mealResponse *MealResponse + err = json.NewDecoder(response.Body).Decode(&mealResponse) + if err != nil { + return nil, err + } + + meals := []*model.MealOverview{} + for _, v := range mealResponse.Meals { + meal, err := createMealOverview(v) + if err != nil { + continue + } + meals = append(meals, meal) + } + + return meals, nil +} + +func createMeal(currentMeal *Meal) (*model.Meal, error) { + meal := &model.Meal{} if currentMeal.IdMeal != nil { id, err := strconv.Atoi(*currentMeal.IdMeal) if err == nil { @@ -311,3 +392,21 @@ func getMeal(mealResponse *MealResponse) (*model.Meal, error) { return meal, nil } + +func createMealOverview(currentMeal *Meal) (*model.MealOverview, error) { + meal := &model.MealOverview{} + if currentMeal.IdMeal != nil { + id, err := strconv.Atoi(*currentMeal.IdMeal) + if err == nil { + meal.ID = id + } + } + if currentMeal.StrMeal != nil { + meal.Name = *currentMeal.StrMeal + } + if currentMeal.StrMealThumb != nil { + meal.ImagePath = *currentMeal.StrMealThumb + } + + return meal, nil +} diff --git a/service/meal/handler/meal.go b/service/meal/handler/meal.go index 40f736011b5f0051f67b960d879909e7abe441cd..069c55bf886bf2578e2a018d0b4157d73657f45c 100644 --- a/service/meal/handler/meal.go +++ b/service/meal/handler/meal.go @@ -3,6 +3,7 @@ package handler import ( "net/http" + "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/meal/model" "gitlab.reutlingen-university.de/yesildas/mealplanner2go/service/meal/service" ) @@ -10,6 +11,57 @@ func GetRandomMeal(w http.ResponseWriter, r *http.Request) { meal, err := service.GetRandomMeal() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) + return } sendJson(w, meal) } + +func GetMeal(w http.ResponseWriter, r *http.Request) { + id, err := getId(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + meal, err := service.GetMeal(id) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + sendJson(w, meal) +} + +func SearchMealByName(w http.ResponseWriter, r *http.Request) { + meals, err := service.SearchMealByName(getValue(r)) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + sendJson(w, meals) +} + +func SearchMealByCategory(w http.ResponseWriter, r *http.Request) { + meals, err := service.SearchMealBy(getValue(r), model.CATEGORY) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + sendJson(w, meals) +} + +func SearchMealByArea(w http.ResponseWriter, r *http.Request) { + meals, err := service.SearchMealBy(getValue(r), model.AREA) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + sendJson(w, meals) +} + +func SearchMealByIngredient(w http.ResponseWriter, r *http.Request) { + meals, err := service.SearchMealBy(getValue(r), model.INGREDIENT) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + sendJson(w, meals) +} diff --git a/service/meal/handler/util.go b/service/meal/handler/utils.go similarity index 51% rename from service/meal/handler/util.go rename to service/meal/handler/utils.go index 406cc030ad33764536c6ff855ba8b921dc3ce45e..7272c8514f0fc4b8989c32129c7b409ba55ae66d 100644 --- a/service/meal/handler/util.go +++ b/service/meal/handler/utils.go @@ -3,6 +3,9 @@ package handler import ( "encoding/json" "net/http" + "strconv" + + "github.com/gorilla/mux" ) func sendJson(w http.ResponseWriter, value interface{}) { @@ -11,3 +14,17 @@ func sendJson(w http.ResponseWriter, value interface{}) { http.Error(w, err.Error(), http.StatusInternalServerError) } } + +func getId(r *http.Request) (int, error) { + vars := mux.Vars(r) + id, err := strconv.Atoi(vars["id"]) + if err != nil { + return 0, err + } + return id, nil +} + +func getValue(r *http.Request) string { + vars := mux.Vars(r) + return vars["value"] +} diff --git a/service/meal/main.go b/service/meal/main.go index b1a674bee69ec5cf043b00c2863a126c794be3e9..3427f29eb3082630afb67f80df9043593af5d819 100644 --- a/service/meal/main.go +++ b/service/meal/main.go @@ -13,6 +13,11 @@ func main() { port := 8000 router := mux.NewRouter() router.HandleFunc("/random", handler.GetRandomMeal).Methods(http.MethodGet) + router.HandleFunc("/search/{value}", handler.SearchMealByName).Methods(http.MethodGet) + router.HandleFunc("/category/{value}", handler.SearchMealByCategory).Methods(http.MethodGet) + router.HandleFunc("/area/{value}", handler.SearchMealByArea).Methods(http.MethodGet) + router.HandleFunc("/ingredient/{value}", handler.SearchMealByIngredient).Methods(http.MethodGet) + router.HandleFunc("/{id}", handler.GetMeal).Methods(http.MethodGet) if err := http.ListenAndServe(fmt.Sprintf(":%v", port), router); err != nil { log.Fatal(err) } diff --git a/service/meal/model/meal.go b/service/meal/model/meal.go index 6d89832dfe7ad078258d908cc028478820957a9d..92c65d03c5e543159d5951cf907f9714d4ee32c0 100644 --- a/service/meal/model/meal.go +++ b/service/meal/model/meal.go @@ -13,3 +13,21 @@ type Meal struct { Instructions string `json:"instructions"` ImagePath string `json:"imagePath"` } + +type MealOverview struct { + ID int `json:"id"` + Name string `json:"name"` + ImagePath string `json:"imagePath"` +} + +type FilterValues struct { + Values []string `json:"values"` +} + +const ( + CATEGORY Filter = "c" + AREA Filter = "a" + INGREDIENT Filter = "i" +) + +type Filter string diff --git a/service/meal/service/meal.go b/service/meal/service/meal.go index 67606da04488b851aa8ddbe3f435389e5e5f78a0..2f51a744604aa3bd938622935e6943ec74301c3a 100644 --- a/service/meal/service/meal.go +++ b/service/meal/service/meal.go @@ -13,3 +13,30 @@ func GetRandomMeal() (*model.Meal, error) { return meal, nil } + +func GetMeal(id int) (*model.Meal, error) { + meal, err := mealdb.GetMeal(id) + if err != nil { + return nil, err + } + + return meal, nil +} + +func SearchMealByName(name string) ([]*model.Meal, error) { + meals, err := mealdb.SearchMealByName(name) + if err != nil { + return nil, err + } + + return meals, nil +} + +func SearchMealBy(value string, filter model.Filter) ([]*model.MealOverview, error) { + meals, err := mealdb.SearchMealBy(value, filter) + if err != nil { + return nil, err + } + + return meals, nil +}