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 实战 - 服务划分与项目创建》

相关推荐
慕城南风1 天前
Go语言中的defer,panic,recover 与错误处理
golang·go
桃园码工2 天前
1-Gin介绍与环境搭建 --[Gin 框架入门精讲与实战案例]
go·gin·环境搭建
云中谷2 天前
Golang 神器!go-decorator 一行注释搞定装饰器,v0.22版本发布
go·敏捷开发
苏三有春3 天前
五分钟学会如何在GitHub上自动化部署个人博客(hugo框架 + stack主题)
git·go·github
我是前端小学生3 天前
Go语言中的方法和函数
go
探索云原生4 天前
在 K8S 中创建 Pod 是如何使用到 GPU 的: nvidia device plugin 源码分析
ai·云原生·kubernetes·go·gpu
自在的LEE4 天前
当 Go 遇上 Windows:15.625ms 的时间更新困局
后端·kubernetes·go
Gvto5 天前
使用FakeSMTP创建本地SMTP服务器接收邮件具体实现。
go·smtp·mailtrap
白泽来了5 天前
【Go进阶】手写 Go websocket 库(一)|WebSocket 通信协议
开源·go
witton5 天前
将VSCode配置成Goland的视觉效果
ide·vscode·编辑器·go·字体·c/c++·goland