您的位置:首页 > 理论基础 > 计算机网络

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

2020-08-27 23:29 1441 查看
  • 3. 处理json tag不一致的问题
  • 1. protobuf相关依赖安装

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

    如下图,解压出来因平台而异会是一个

    protoc
    或者
    protoc.exe

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

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

    安装后会在

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

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

    2. 改造之前的client

    2.1 新建proto文件

    • 新建
      models/protos
      文件夹
    • 在上述文件夹下新建
      prod.proto
      文件,内容如下:
    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
    文件夹下运行以下命令

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

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

    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修改成一样的才可以

    这里可以使用插件修改

    第一步:下载插件

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

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

    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;
    }

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

    protoc-go-inject-tag -input=../prods.pb.go
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: