go微服务系列(四) - http api中引入protobuf

1. protobuf相关依赖安装#

  • 第一步:下载grpc通用编译器

如下图,解压出来因平台而异会是一个protoc或者protoc.exe

https://github.com/protocolbuffers/protobuf/releases

  • 第二步:把下载的二进制文件路径添加到环境变量中(为了能全局访问protoc)
    • 这里以为mac为例子
Copy
# 打开这个 vim /etc/paths # 把路径添加进去 /Users/emm/others/protoc-3.12.4-osx-x86_64/bin/protoc # 刷新环境变量 source /etc/paths
  • 第三步: 安装go专用的protoc的生成器
Copy
go get github.com/golang/protobuf/protoc-gen-go

安装后会在GOPATH目录下生成可执行文件,protobuf的编译器插件protoc-gen-go,等下执行protoc命令会自动调用这个插件

  • 第四步: 安装go-micro对应的插件
Copy
go get github.com/micro/protoc-gen-micro

2. 改造之前的client#

2.1 新建proto文件#

  • 新建models/protos文件夹
  • 在上述文件夹下新建prod.proto文件,内容如下:
Copy
syntax = "proto3"; package Models; message ProdModel { int32 Id = 1; string Name = 2; } message ProdRequest { int32 Size = 1; } message ProdListResponse{ repeated ProdModel data = 1; }

2.2 运行protoc命令生成go文件#

models/protos文件夹下运行以下命令

Copy
protoc --micro_out=../ --go_out=../ prods.proto

2.3 然后把原来的map修改成具体的类型就可以了#

Copy
package main import ( "context" "fmt" "gomicro-quickstart/goplugin_http_proto_invoker/models" "log" "github.com/micro/go-micro/client" "github.com/micro/go-micro/client/selector" "github.com/micro/go-micro/registry" "github.com/micro/go-plugins/client/http" "github.com/micro/go-plugins/registry/consul" ) func main() { // 1. 注册consul地址 cr := consul.NewRegistry(registry.Addrs("47.100.220.174:8500")) // 2. 实例化selector mySelector := selector.NewSelector( selector.Registry(cr), // 传入上面的consul selector.SetStrategy(selector.RoundRobin), // 指定获取实例的算法 ) // 3. 请求服务 resp, err := callByGoPlugin(mySelector) if err != nil { log.Fatal("request API failed", err) } fmt.Printf("[服务调用结果]:\r\n %v", resp) } func callByGoPlugin(s selector.Selector) ([]*models.ProdModel, error) { // 1. 调用`go-plugins/client/http`包的函数获取它们提供的httpClient gopluginClient := http.NewClient( client.Selector(s), // 传入上面的selector client.ContentType("application/json"), // 指定contentType ) // 2. 新建请求对象,传入: (1)服务名 (2)endpoint (3)请求参数 req := gopluginClient.NewRequest("ProductService", "/v1/list", models.ProdRequest{Size: 2}) // 3. 新建响应对象,并call请求,获取响应 var resp models.ProdListResponse err := gopluginClient.Call(context.Background(), req, &resp) if err != nil { return nil, err } return resp.GetData(), nil }

3. 处理json tag不一致的问题#

如果服务端的model设置了json tag,如下

只有将客户端的proto文件生成的pb.go文件中的model的tag修改成一样的才可以

这里可以使用插件修改

第一步:下载插件

Copy
go get -u github.com/favadi/protoc-go-inject-tag

第二步,在proto文件上加注释

Copy
syntax = "proto3"; package models; message ProdModel { // @inject_tag: json:"pid" int32 Id = 1; // @inject_tag: json:"pname" string Name = 2; } message ProdRequest { int32 Size = 1; } message ProdListResponse{ repeated ProdModel data = 1; }

第三步:使用命令行批量修改

Copy
protoc-go-inject-tag -input=../prods.pb.go
posted @   宝树呐  阅读(4041)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示
CONTENTS