go-zero 实战 - Food DeleteFood

174 阅读2分钟

我们通过一个系列文章跟大家详细展示一个 go-zero 微服务实例,整个系列分十三篇文章,目录结构如下:

  1. go-zero 实战 - 服务划分与项目创建
  2. go-zero 实战 - User API Gateway
  3. go-zero 实战 - User Login
  4. go-zero 实战 - User Register
  5. go-zero 实战 - User Userinfo
  6. go-zero 实战 - Food API Gateway
  7. go-zero 实战 - Food Search
  8. go-zero 实战 - Food AddFood
  9. go-zero 实战 - Food DeleteFood
  10. go-zero 实战 - Food Foodlist
  11. go-zero 实战进阶 - rpc 服务
  12. go-zero 实战进阶 - 用户管理 rpc 服务
  13. go-zero 实战进阶 - 食材管理 rpc 服务

期望通过本系列文章带你在本地利用 go-zero 快速开发一个《食谱指南》系统,让你快速上手微服务。

上一篇 文章中我们介绍了如何搭建向指定用户添加食材的接口,本篇在此基础上介绍如何搭建删除指定用户食材的接口。

添加删除接口逻辑

$ vim foodmanage/api/internal/logic/deletefoodlogic.go

package logic

import (
    "context"
    "database/sql"
    "encoding/json"
    "errors"
    "fmt"
    "strconv"

    "FoodGuides/service/foodmanage/api/internal/svc"
    "FoodGuides/service/foodmanage/api/internal/types"

    "github.com/zeromicro/go-zero/core/logx"
)

type DeleteFoodLogic struct {
    logx.Logger
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func NewDeleteFoodLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteFoodLogic {
    return &DeleteFoodLogic{
       Logger: logx.WithContext(ctx),
       ctx:    ctx,
       svcCtx: svcCtx,
    }
}

func (l *DeleteFoodLogic) DeleteFood(req *types.DeleteFoodRequest) (*types.DeleteFoodResponse, error) {
    // 获取 jwt 载体中 `uid` 信息,
    uid, _ := l.ctx.Value("uid").(json.Number).Int64()
    foodId, _ := strconv.ParseInt(req.FoodId, 10, 64)
    userFood, _ := l.svcCtx.UserFoodModel.FindOneByUserid(l.ctx, sql.NullInt64{
       Int64: uid,
       Valid: true,
    })

    if userFood == nil {
       return nil, errors.New(fmt.Sprintf("该用户名下没有关联的食物,用户 ID:%d", uid))
    }

    if userFood.Foodid.Int64 != foodId {
       return nil, errors.New(fmt.Sprintf("该用户名下没有此关联的食物,用户 ID:%d, 食物 ID: %d", uid, foodId))
    }

    err := l.svcCtx.UserFoodModel.Delete(l.ctx, userFood.Id)

    if err != nil {
       return nil, err
    }

    return &types.DeleteFoodResponse{}, nil
}

修改 Response 返回格式

$ vim foodmanage/api/internal/handler/deletefoodhandler.go

package handler

import (
    "FoodGuides/common/responsex"
    "net/http"

    "FoodGuides/service/foodmanage/api/internal/logic"
    "FoodGuides/service/foodmanage/api/internal/svc"
    "FoodGuides/service/foodmanage/api/internal/types"
    "github.com/zeromicro/go-zero/rest/httpx"
)

func DeleteFoodHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
       var req types.DeleteFoodRequest
       if err := httpx.Parse(r, &req); err != nil {
          httpx.OkJson(w, responsex.FailureResponse(nil, err.Error(), 1000))
          return
       }

       l := logic.NewDeleteFoodLogic(r.Context(), svcCtx)
       resp, err := l.DeleteFood(&req)
       if err != nil {
          httpx.OkJson(w, responsex.FailureResponse(nil, err.Error(), 1000))
       } else {
          httpx.OkJson(w, responsex.SuccessResponse(resp, "删除成功"))
       }
    }
}

启动服务

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

➜  service: 
$ go run foodmanage/api/food.go -f foodmanage/api/etc/food-api.yaml
Starting server at 0.0.0.0:8889...

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

  1. PostmanAuthorization 选项中选择 Bearer Token,填写登录成功后 Api 返回的 accessToken 字段值。
  2. PostmanBody 选项中选择 raw,并设置内容为 {"foodId": "1"}

点击发送请求按钮,有如下截图的响应说明接口运行正常。

image.png

数据库表 user_food 中匹配的记录也同时被删除了。至此,Food - DeleteFood 接口就开发完成了。下篇我们将介绍如何搭建获取指定用户食谱列表的接口。

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

下一篇《go-zero 实战 - Food Foodlist》