API Gateway
代码调用 food api
服务
编辑 api/internal/handler
下的 foodlisthandler.go
文件,修改 FoodListHandler
方法如下:
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
需要返回指定用户下的所有食物信息,因此需要先根据 userId
从 user_food
表中查询所有匹配到记录的 foodid
集合,再利用 foodid
集合从 food
表中查询到所有匹配到的 food
集合。
编辑 model
下的 userfoodmodel_gen.go
文件,添加方法 FindManyByUserid
,表示根据 userId
从 user_food
表中查询所有匹配到记录的 UserFood
集合:
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
接口中新增该方法的声明:
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
集合:
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
接口中新增该方法的声明:
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
如下:
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
端口
➜ 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
接口:
Postman
的 Authorization
选项中选择 Bearer Token
,填写登录成功后 Api
返回的 accessToken
字段值。这样 Food - Foodlist 就开发完成了。
上一篇《go-zero 实战 - Food DeleteFood》
首篇《go-zero 实战 - 服务划分与项目创建》