go-zero 实战 - Food Foodlist

API Gateway 代码调用 food api 服务

编辑 api/internal/handler 下的 foodlisthandler.go 文件,修改 FoodListHandler 方法如下:

go 复制代码
func FoodListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
       l := logic.NewFoodListLogic(r.Context(), svcCtx)
       resp, err := l.FoodList()
       if err != nil {
          httpx.OkJson(w, renpanpan.FailureResponse(nil, err.Error(), 1000))
       } else {
          httpx.OkJson(w, renpanpan.SuccessResponse(resp, "请求成功"))
       }
    }
}

因为 /food/foodlist 需要返回指定用户下的所有食物信息,因此需要先根据 userIduser_food 表中查询所有匹配到记录的 foodid 集合,再利用 foodid 集合从 food 表中查询到所有匹配到的 food 集合。

编辑 model 下的 userfoodmodel_gen.go 文件,添加方法 FindManyByUserid,表示根据 userIduser_food 表中查询所有匹配到记录的 UserFood 集合:

go 复制代码
func (m *defaultUserFoodModel) FindManyByUserid(ctx context.Context, userid int64) ([]*UserFood, error) {
    var resp []*UserFood
    query := fmt.Sprintf("select %s from %s where `userid` = ?", userFoodRows, m.table)
    err := m.conn.QueryRowsCtx(ctx, &resp, query, userid)
    switch err {
    case nil:
       return resp, nil
    case sqlc.ErrNotFound:
       return nil, ErrNotFound
    default:
       return nil, err
    }
}

同时在 userfoodmodel_gen.go 文件的 userFoodModel 接口中新增该方法的声明:

go 复制代码
type (
    userFoodModel interface {
       Insert(ctx context.Context, data *UserFood) (sql.Result, error)
       FindOne(ctx context.Context, id int64) (*UserFood, error)
       FindOneByUserid(ctx context.Context, userid int64) (*UserFood, error)
       FindManyByUserid(ctx context.Context, userid int64) ([]*UserFood, error) // 新增方法声明
       Update(ctx context.Context, data *UserFood) error
       Delete(ctx context.Context, id int64) error
    }

    defaultUserFoodModel struct {
       conn  sqlx.SqlConn
       table string
    }

    UserFood struct {
       Id         int64     `db:"id"`     // id
       Userid     int64     `db:"userid"` // 用户Id
       Foodid     int64     `db:"foodid"` // 食物Id
       CreateTime time.Time `db:"create_time"`
       UpdateTime time.Time `db:"update_time"`
    }
)

编辑 model 下的 foodmodel_gen.go 文件,添加方法 FindMany,表示根据 foodid 集合从 food 表中查询到所有匹配到的 food 集合:

go 复制代码
func (m *defaultFoodModel) FindMany(ctx context.Context, ids []string) ([]*Food, error) {
    query := fmt.Sprintf("select %s from %s where `id` in (%s)", foodRows, m.table, strings.Join(ids, ","))
    var resp []*Food
    err := m.conn.QueryRows(&resp, query)
    switch err {
    case nil:
       return resp, nil
    case sqlc.ErrNotFound:
       return nil, ErrNotFound
    default:
       return nil, err
    }
}

同样在 foodmodel_gen.go 文件的 foodModel 接口中新增该方法的声明:

go 复制代码
type (
    foodModel interface {
       Insert(ctx context.Context, data *Food) (sql.Result, error)
       FindOne(ctx context.Context, id int64) (*Food, error)
       FindMany(ctx context.Context, ids []string) ([]*Food, error) // 新增方法声明
       FindOneByName(ctx context.Context, name string) (*Food, error)
       Update(ctx context.Context, data *Food) error
       Delete(ctx context.Context, id int64) error
    }

    defaultFoodModel struct {
       conn  sqlx.SqlConn
       table string
    }

    Food struct {
       Id           int64     `db:"id"`           // 食物Id
       Name         string    `db:"name"`         // 食物名称
       Protein      string    `db:"protein"`      // 食物蛋白质含量
       Fat          string    `db:"fat"`          // 食物脂肪含量
       Carbohydrate string    `db:"carbohydrate"` // 食物碳水化合物含量
       Calorie      string    `db:"calorie"`      // 食物卡路里
       Minerals     string    `db:"minerals"`     // 食物矿物质含量
       Calcium      string    `db:"calcium"`      // 食物钙含量
       Phosphorus   string    `db:"phosphorus"`   // 食物磷含量
       Iron         string    `db:"iron"`         // 食物铁含量
       Purine       string    `db:"purine"`       // 食物嘌呤含量
       CreateTime   time.Time `db:"create_time"`
       UpdateTime   time.Time `db:"update_time"`
    }
)

至此,我们已经准备好数据来源的查询方法,编辑 api/internal/logic 下的 foodlistlogic.go 文件,修改方法 FoodList 如下:

go 复制代码
func (l *FoodListLogic) FoodList() (*types.FoodResponse, error) {
    
    userId, _ := l.ctx.Value("userId").(json.Number).Int64()
    userFoods, err := l.svcCtx.UserFood.FindManyByUserid(l.ctx, userId)
    if err != nil {
       return nil, err
    }
    
    var foodIds []string
    for _, food := range userFoods {
       foodIds = append(foodIds, strconv.FormatInt(food.Foodid, 10))
    }
    foods, err1 := l.svcCtx.Food.FindMany(l.ctx, foodIds)
    if err1 != nil {
       return nil, err1
    }

    var foodReplys []types.FoodReply

    for _, food := range foods {
       foodReply := types.FoodReply{
          Id:           strconv.FormatInt(food.Id, 10),
          Name:         food.Name,
          Protein:      food.Protein,
          Fat:          food.Fat,
          Carbohydrate: food.Carbohydrate,
          Calorie:      food.Calorie,
          Minerals:     food.Minerals,
          Calcium:      food.Calcium,
          Phosphorus:   food.Phosphorus,
          Iron:         food.Iron,
          Purine:       food.Purine,
       }
       foodReplys = append(foodReplys, foodReply)
    }

    return &types.FoodResponse{List: foodReplys}, nil
}

启动服务

启动 food api 服务, 运行成功后,food api 则运行在本机的 8889 端口

bash 复制代码
➜  FoodGuides: 
$ go run foodmanage/api/food.go -f foodmanage/api/etc/food-api.yaml
Starting server at 0.0.0.0:8889...

我们用 Postman 尝试请求 /food/foodlist 接口:

  1. PostmanAuthorization 选项中选择 Bearer Token,填写登录成功后 Api 返回的 accessToken 字段值。
  2. 点击发送请求按钮,有如下截图的响应说明接口运行正常。

这样 Food - Foodlist 就开发完成了。

上一篇《go-zero 实战 - Food DeleteFood》

首篇《go-zero 实战 - 服务划分与项目创建》

相关推荐
梦想很大很大9 小时前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go
lekami_兰14 小时前
MySQL 长事务:藏在业务里的性能 “隐形杀手”
数据库·mysql·go·长事务
却尘17 小时前
一篇小白也能看懂的 Go 字符串拼接 & Builder & cap 全家桶
后端·go
ん贤18 小时前
一次批量删除引发的死锁,最终我选择不加锁
数据库·安全·go·死锁
mtngt111 天前
AI DDD重构实践
go
Grassto3 天前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto4 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室5 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题5 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo
啊汉7 天前
古文观芷App搜索方案深度解析:打造极致性能的古文搜索引擎
go·软件随想