Skip to content

Commit

Permalink
adding recipe routes to api
Browse files Browse the repository at this point in the history
  • Loading branch information
mlinder10 committed Jun 27, 2024
1 parent 6f0592b commit a0a9f35
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 4 deletions.
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ func main() {
router.POST("/auth/login", routes.Login)
router.POST("/auth/register", routes.Register)

router.GET("/recipes", routes.GetUserRecipes)
// router.POST("/recipes", routes.CreateRecipe)

// Start server
router.Run(":8080")
}
7 changes: 7 additions & 0 deletions models/ingredient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package models

type Ingredient struct {
Name string `json:"name"`
Unit string `json:"unit"`
Quantity float64 `json:"quantity"`
}
85 changes: 85 additions & 0 deletions models/recipe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package models

import (
"database/sql"
"encoding/json"
"strings"

"github.com/google/uuid"
)

type Recipe struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Ingredients []Ingredient `json:"ingredients"`
}

func CreateRecipe(db *sql.DB, name string, description string, ingredients []Ingredient) (Recipe, error) {
recipe := Recipe{
ID: uuid.New(),
Name: name,
Description: description,
Ingredients: ingredients,
}

jsonIngredients, err := json.Marshal(recipe.Ingredients)
if err != nil {
return Recipe{}, err
}

_, err = db.Exec("INSERT INTO recipes (id, name, description, ingredients) VALUES (?, ?, ?, ?)",
recipe.ID, recipe.Name, recipe.Description, jsonIngredients)
if err != nil {
return Recipe{}, err
}

return recipe, nil
}

func GetUserRecipes(db *sql.DB, token string) ([]Recipe, error) {
user, err := GetUser(db, uuid.MustParse(token))
if err != nil {
return nil, err
}

var recipeIds []string

rows, err := db.Query("SELECT rid FROM user_recipe WHERE uid = ?", user.ID)
if err != nil {
return nil, err
}

defer rows.Close()

for rows.Next() {
var recipeId string
if err := rows.Scan(&recipeId); err != nil {
return nil, err
}
recipeIds = append(recipeIds, recipeId)
}

rows, err = db.Query("SELECT id, name, description, ingredients FROM recipes WHERE id IN (" + strings.Join(recipeIds, ",") + ")")
if err != nil {
return nil, err
}

defer rows.Close()

var recipes []Recipe
for rows.Next() {
var recipe Recipe
var jsonIngredients string
if err := rows.Scan(&recipe.ID, &recipe.Name, &recipe.Description, &jsonIngredients); err != nil {
return nil, err
}
err := json.Unmarshal(([]byte)(jsonIngredients), &recipe.Ingredients)
if err != nil {
return nil, err
}
recipes = append(recipes, recipe)
}

return recipes, nil
}
38 changes: 36 additions & 2 deletions models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ type User struct {

func LoginUser(db *sql.DB, email string, password string) (User, error) {
var user User
var hashedPassword string
var createdAt, updatedAt, tokenExpiration sql.NullTime
var id, token sql.NullString

err := db.QueryRow("SELECT id, email, username, password, created_at, updated_at, token, token_expiration FROM users WHERE email = ? AND password = ?", email, password).
Scan(&id, &user.Email, &user.Username, &hashedPassword, &createdAt, &updatedAt, &token, &tokenExpiration)
Scan(&id, &user.Email, &user.Username, &user.Password, &createdAt, &updatedAt, &token, &tokenExpiration)

if err != nil {
if err == sql.ErrNoRows {
Expand Down Expand Up @@ -74,3 +73,38 @@ func RegisterUser(db *sql.DB, email string, username string, password string) (U

return user, nil
}

func GetUser(db *sql.DB, token uuid.UUID) (User, error) {
var user User
var createdAt, updatedAt, tokenExpiration sql.NullTime
var id, tokenString sql.NullString

err := db.QueryRow("SELECT id, email, username, created_at, updated_at, token, token_expiration FROM users WHERE token = ?", token).
Scan(&id, &user.Email, &user.Username, &createdAt, &updatedAt, &tokenString, &tokenExpiration)

if err != nil {
if err == sql.ErrNoRows {
return User{}, errors.New("user not found")
}
return User{}, err
}

// Parse UUID and time fields
if id.Valid {
user.ID, _ = uuid.Parse(id.String)
}
if createdAt.Valid {
user.CreatedAt = createdAt.Time
}
if updatedAt.Valid {
user.UpdatedAt = updatedAt.Time
}
if tokenString.Valid {
user.Token, _ = uuid.Parse(tokenString.String)
}
if tokenExpiration.Valid {
user.TokenExpiration = tokenExpiration.Time
}

return user, nil
}
6 changes: 4 additions & 2 deletions routes/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ func DBMiddleware(c *gin.Context) {

func AuthMiddleware(c *gin.Context) {
apiToken := os.Getenv("API_KEY")
token := c.GetHeader("Authorization")
if token != apiToken {
authToken := c.GetHeader("Authorization")
if authToken != apiToken {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
c.Abort()
return
}
token := c.GetHeader("Token")
c.Set("token", token)
c.Next()
}
43 changes: 43 additions & 0 deletions routes/recipe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package routes

import (
"CookingApp/models"
"database/sql"
"net/http"

"github.com/gin-gonic/gin"
)

type createRecipeBody struct {
Name string `json:"name"`
Description string `json:"description"`
Ingredients []models.Ingredient `json:"ingredients"`
}

func CreateRecipe(c *gin.Context) {
db := c.MustGet("db").(*sql.DB)

var body createRecipeBody
if err := c.BindJSON(&body); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}

recipe, err := models.CreateRecipe(db, body.Name, body.Description, body.Ingredients)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusCreated, recipe)
}

func GetUserRecipes(c *gin.Context) {
db := c.MustGet("db").(*sql.DB)
token := c.MustGet("token").(string)
recipes, err := models.GetUserRecipes(db, token)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, recipes)
}

0 comments on commit a0a9f35

Please sign in to comment.