go-zero教程——Food rpc - Search

1,151 阅读4分钟

Food rpc创建

cdFoodGuides 目录下。创建 rpc 文件夹

mkdir -p foodmanage/rpc/food && cd foodmanage/rpc/food

rpc/food 目录下编写 food.proto 文件

goctl rpc template -o food.proto

编写 food.proto 文件

syntax = "proto3";

package food;

message SearchRequest {
  string key = 1;
}

message AddFoodRequest {
  string userid = 1;
  string foodid = 2;
}

message DeleteFoodRequest {
  string id = 1;
}

message FoodListRequest {
  string userid = 1;
}

message SearchResponse {
  string protein = 1;
  string fat = 2;
  string carbohydrate = 3;
  string calorie = 4;
  string minerals = 5;
  string calcium = 6;
  string phosphorus = 7;
  string iron = 8;
  string purine = 9;
  string id = 10;
  string name = 11;
}

message StatusResponse {
  int32 success = 1;
}

message FoodListResponse {
}
service Food {
  rpc Search(SearchRequest) returns(SearchResponse);
  rpc AddFood(AddFoodRequest) returns(StatusResponse);
  rpc DeleteFood(DeleteFoodRequest) returns(StatusResponse);
  rpc FoodList(FoodListRequest) returns(FoodListResponse);
}

我们定义了三个接口 :Search AddFood DeleteFood FoodList 生成 food-rpc 服务

goctl rpc proto -src food.proto -dir .

查看一下 rpc/food 目录

➜  food git:(master) ✗ tree
.
├── etc
│   └── food.yaml
├── food
│   └── food.pb.go
├── food.go
├── food.proto
├── foodclient
│   └── food.go
└── internal
    ├── config
    │   └── config.go
    ├── logic
    │   ├── addfoodlogic.go
    │   ├── deletefoodlogic.go
    │   ├── foodlistlogic.go
    │   └── searchlogic.go
    ├── server
    │   └── foodserver.go
    └── svc
        └── servicecontext.go

8 directories, 12 files
➜  food git:(master) ✗

API Gateway 代码调用 food rpc 服务

编辑 api/etc 下的 food-api.yaml 文件,新增 food.rpc 配置

Name: food-api
Host: 0.0.0.0
Port: 8889

Food:
  Etcd:
    Hosts:
      - localhost:2379
    Key: food.rpc

编辑 api/internal/config 下的 config.go 文件,新增 Food 变量

type Config struct {
	rest.RestConf
	Food foodclient.Food
	Auth struct {
		AccessSecret string
		AccessExpire int64
	}
}

编辑 api/internal/svc 下的 servicecontext.go 文件,新增 Food 变量 ,新增实例化代码。

type ServiceContext struct {
	Config config.Config
	Food foodclient.Food
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config: c,
		Food: foodclient.NewFood(zrpc.MustNewClient(c.Food)),
	}
}

编辑 api/internal/logic 下的 searchlogic.go 文件,新增 调用 food rpcsearch 方法

func (l *SearchLogic) Search(req types.SearchRequest) (*types.SearchResponse, error) {

	resp,err := l.svcCtx.Food.Search(l.ctx,&food.SearchRequest{
		Key: req.Key,
	})
	if err != nil {
		return nil, err
	}

	return &types.SearchResponse{
		FoodReply: types.FoodReply{
			Id: resp.Id,
			Name: resp.Name,
			Protein: resp.Protein,
			Fat: resp.Fat,
			Carbohydrate: resp.Carbohydrate,
			Calorie: resp.Calorie,
			Minerals: resp.Minerals,
			Calcium: resp.Calcium,
			Phosphorus: resp.Phosphorus,
			Iron: resp.Iron,
			Purine: resp.Purine,
		},
	}, nil
}

定义数据库表结构,并生成CRUD+cache代码

foodmanage 下创建 model 文件夹。

mkdir -p model & cd model

model 下新建 food.sql 文件并编写如下内容。

CREATE TABLE `food` (
                        `id` bigint NOT NULL AUTO_INCREMENT COMMENT '食物Id',
                        `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物名称',
                        `protein` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物蛋白质含量',
                        `fat` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物脂肪含量',
                        `carbohydrate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物碳水化合物含量',
                        `calorie` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物卡路里',
                        `minerals` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物矿物质含量',
                        `calcium` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物钙含量',
                        `phosphorus` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物磷含量',
                        `iron` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物铁含量',
                        `purine` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '食物嘌呤含量',
                        `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
                        `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                        PRIMARY KEY (`id`),
                        UNIQUE KEY `name_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

model 目录下执行如下命令生成 CRUD+cache 代码,-c 表示使用 redis cache

goctl model mysql ddl -c -src food.sql -dir .

查看 model 目录结构

➜  model git:(master) ✗ tree
.
├── food.sql
├── foodmodel.go // CRUD+cache代码
└── vars.go      // 定义常量和变量

0 directories, 3 files
➜  model git:(master) ✗

在本机 mysql 中创建 foodguides 数据库,并新建 food 表。

新增一条数据

INSERT INTO `foodguides`.`food`(`id`, `name`, `protein`, `fat`, `carbohydrate`, `calorie`, `minerals`, `calcium`, `phosphorus`, `iron`, `purine`, `create_time`, `update_time`) VALUES (1, '鱿鱼', '60.0', '4.6', '7.8', '1323', '100', '87', '392', '4.1', '100', '2021-01-26 23:30:43', '2021-01-26 23:33:38');

rpc 代码调用 crud+cache 代码

编辑 rpc/food/etc 下的 food.yaml 文件,新增如下内容。

注意这里的 mysql 使用的是 ningxi-compose 跑的 docker 容器,因此参数需要注意。

Name: food.rpc
ListenOn: 127.0.0.1:8089
Etcd:
  Hosts:
  - 127.0.0.1:2379
  Key: food.rpc

DataSource: root:2e70F5E6@(localhost:13306)/foodguides?parseTime=true
Table: food
Cache:
  - Host: localhost:16379

编辑 rpc/food/internal/config 下的 config.go 文件,新增 DataSource Cache 变量

type Config struct {
	zrpc.RpcServerConf
	DataSource string
	Cache cache.CacheConf
}

编辑 rpc/food/internal/svc 下的 serviceContext.go 文件,新增 Model 变量 ,新增实例化代码。

type ServiceContext struct {
	Config config.Config
	Model model.FoodModel
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config: c,
		Model: model.NewFoodModel(sqlx.NewMysql(c.DataSource),c.Cache),
	}
}

编辑 rpc/food/internal/logic 下的 searchlogic.go 文件, 新增如下代码

func (l *SearchLogic) Search(in *food.SearchRequest) (*food.SearchResponse, error) {
	res, err := l.svcCtx.Model.FindOneByName(in.Key)
	if err == nil {
		newid :=strconv.FormatInt(res.Id,10)
		return &food.SearchResponse{
			Id: newid,
			Name: res.Name,
			Protein: res.Protein,
			Fat: res.Fat,
			Carbohydrate: res.Carbohydrate,
			Calorie: res.Calorie,
			Minerals: res.Minerals,
			Calcium: res.Calcium,
			Phosphorus: res.Phosphorus,
			Iron: res.Iron,
			Purine: res.Purine,
		}, nil
	} else {
		return nil,err
	}
}

启动服务

启动服务,注意 在启动服务前,需要确保 上一篇文章用到的 ningxi-compose 正常运行起来。

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

➜  FoodGuides git:(master) ✗ go run foodmanage/rpc/food/food.go -f foodmanage/rpc/food/etc/food.yaml
Starting rpc server at 127.0.0.1:8089...

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

➜  FoodGuides git:(master) ✗ go run foodmanage/api/food.go -f foodmanage/api/etc/food-api.yaml
Starting server at 0.0.0.0:8889...

api 测试 得到如下数据则说明 服务运行正常

➜  ~ curl http://localhost:8889/food/search -X POST -d '{"key": "鱿鱼"}' --header "Content-Type: application/json"

{"code":1,"message":"搜索成功","result":{"id":"1","name":"鱿鱼","protein":"60.0","fat":"4.6","carbohydrate":"7.8","calorie":"1323","minerals":"100","calcium":"87","phosphorus":"392","iron":"4.1","purine":"100"}}%
➜  ~

这样 Food rpc - Search 就开发完成了。

上一篇《go-zero教程——Food API Gateway》

下一篇《go-zero教程——Food rpc - AddFood》