go-kit

go-kit Truss 代码生成

2021-12-15  本文已影响0人  Mr_窦先生

go-kit Truss 代码生成

依赖

前提

Truss 安装

请参考: MacOS go-kit 自动生成代码工具 truss 安装

ProtoBuf 规范基本说明

请参考: go-kit Truss Protobuf 3 语法基本规范

Truss 使用

1. 创建项目

举个例子:

mkdir -p ~/goWork/truss_demo

2. 定义 protobuf

例如:vim ~/goWork/truss_demo/demo.proto

syntax = "proto3";
package demo;

import "github.com/metaverse/truss/deftree/googlethirdparty/annotations.proto";
import "google/protobuf/any.proto";
import "google/protobuf/struct.proto";

service MyDemo {

  // 获取
  rpc GetSomething (DefaultRequest) returns (DefaultResponse) {
    option (google.api.http) = {

      get: "/my_demo_service/something"

      additional_bindings {
        get: "/my_demo_service/something"
      }
    };
  }
  // 提交
  rpc PostSomething (PostSomethingRequest) returns (DefaultResponse) {
    option (google.api.http) = {
      custom {
        kind: "HEAD"
        path: "/my_demo_service/something"
      }
      additional_bindings {
        post: "/my_demo_service/something"
        body: "*"
      }
    };
  }
}

message DefaultRequest {
  string query = 1;
  string fields = 2;
  string order = 3;
  string sortby = 4;
  int64 limit = 5;
  int64 offset = 6;
}

message PostSomethingRequest {
  string id = 1;
  string name = 2;
  string age = 3;
}

message DefaultResponse {
  string message = 1;
  int64 code = 2;
  google.protobuf.Struct data = 3;
}

3. 初始化 go mod

go mod init my_demo

如图:

mod初始化.png

4. 生成代码

cd ~/goWork/truss_demo
truss ./demo.proto

执行完成后,会自动生成以下内容:

appledeMacBook-Pro:truss_demo apple$ truss ./demo.proto
appledeMacBook-Pro:truss_demo apple$ ls
demo.pb.go  demo.proto  go.mod      mydemo-service
appledeMacBook-Pro:truss_demo apple$ 

如图:

truss代码生成.png

结构图:

truss文件结构.png
结构说明
truss_demo
  |
    |--demo.proto // protobuf 文件
    |--demo.pb.go // RPC接口以及数据结构定义--自动生成
    |--mydemo-service
            |
            |--cmd
            |    |
            |    |--mydemo
            |        |- main.go // 入口 - 自动生成,除特殊情况不建议修改
            |
      |--handlers //业务逻辑--需要我们写代码的地方
      |    |
      |    |--handlers.go //实际业务逻辑
      |    |--hooks.go // 配置信息以及阻断处理
      |    |--middlewares.go //中间件
      |
      |--svc // 通讯协议以及客户端,自动生成,除特殊情况不建议修改
      |  |
      |  |--client // 客户端定义
      |  |   |
      |  |   |--grpc
      |  |   |  |--client.go
      |  |   |--http
      |  |      |--client.go
      |  |--server // 服务端定义
      |  |  |--run.go 
      |  |
      |  |-- config.go // 服务端口定义
      |  |-- endpoints.go //接口定义
      |  |-- transport_grpc.go // grpc 传输协议层
      |  |-- transport_http.go // http 传输协议层

4. 导入包

最后记得使用 go mod 导入依赖。

go mod tidy

如图:


mod_tidy.png

5. 运行

go run mydemo-service/cmd/mydemo/main.go

如图:


go_run.png

6. 打包编译

最终项目发布时需要打包为 Linux 可执行程序。

如下所示:

cd ~/goWork/truss_demo && \
mkdir -p build &&  \
GOARCH=amd64 CGO_ENABLED=0 GOOS=linux go build -o build/main mydemo-service/cmd/mydemo/main.go

最后会在当前目录创建 build 文件夹,同时在 build 文件夹下生成 main 程序。
启动 mian 程序: ./main 即可。

7. 访问测试

不指定端口情况下默认端口分别为:

http: 5050
rpc: 5040
debug: 5060

因为没有写业务逻辑,返回值为默认值:

postman 测试:


postman_test.png

curl 测试:

curl --location --request GET 'localhost:5050/my_demo_service/something' -w "\n"

结果如图:


curl_test.png

特殊情况

数据结构不确定

对于上面 protobuf 定义时,有一种特殊情况需要注意:请求数据结构不确定。

我遇到的情况是:
因为业务需求,需要我提供一个回调接口,用来接收三方程序执行过程信息,但是并不知道具体数据结构,在咨询过 truss 的开发人员后得知,这种情况需要特殊处理。

这时需要将 OPTIONPOST 分开处理:

重新编辑 demo.proto

vim ~/demo.proto

编辑后:

syntax = "proto3";
package demo;

import "github.com/metaverse/truss/deftree/googlethirdparty/annotations.proto";
import "google/protobuf/any.proto";
import "google/protobuf/struct.proto";

service MyDemo {

  // 获取
  rpc GetSomething (DefaultRequest) returns (DefaultResponse) {
    option (google.api.http) = {

      get: "/my_demo_service/something"

      additional_bindings {
        get: "/my_demo_service/something"
      }
    };
  }
  // 提交
  rpc PostSomething (PostSomethingRequest) returns (DefaultResponse) {
    option (google.api.http) = {
      custom {
        kind: "HEAD"
        path: "/my_demo_service/something"
      }
      additional_bindings {
        post: "/my_demo_service/something"
        body: "*"
      }
    };
  }
  // 特殊请求
  rpc SpecialPost (SpecialPostRequest) returns (DefaultResponse) {
    option (google.api.http) = {
      post: "/my_demo_service/special/{id}"
      body : "*"
    };
  }

  // 特殊请求
  rpc SpecialPostHEAD (Empty) returns (Empty) {
    option (google.api.http) = {
      custom {
        kind: "HEAD"
        path: "/my_demo_service/special/*"
      }
    };
  }
}


message Empty {}
message DefaultRequest {
  string query = 1;
  string fields = 2;
  string order = 3;
  string sortby = 4;
  int64 limit = 5;
  int64 offset = 6;
}

message PostSomethingRequest {
  string id = 1;
  string name = 2;
  string age = 3;
}


message SpecialPostRequest {
  string id = 1;
  google.protobuf.Any metadata = 2;
}

message DefaultResponse {
  string message = 1;
  int64 code = 2;
  google.protobuf.Struct data = 3;
}

重新生成代码

经过调整后 protobuf 文件发生变化,这时重新执行生成代码命令即可。

truss ./demo.proto

成功时返回:

appledeMacBook-Pro:truss_demo apple$ truss ./demo.proto
INFO[0000] Generating handler from rpc definition        Method=SpecialPost
INFO[0000] Generating handler from rpc definition        Method=SpecialPostHEAD

如图:

truss代码重生成.png

注意:重生成代码时,如果方法名称发生变化,会导致业务逻辑代码被删除

例如: 上例中 PostSomething 改为PostSomethings, 会导致原有与 PostSomething相关内容被删除,之后新创建 PostSomethings 相关方法。

其他

关于protobufmessage 定义特殊数据,protobuf 并不支持 golang 中的 interface 类型,具体如何接收/解析不确定数据将在下篇文章中介绍,上面其实也有提及,感兴趣的朋友可以先提前去看一下 google/protobuf/any.proto 以及 google/protobuf/structs.proto.

这次先介绍到这里,如有错误,欢迎留言指正。

上一篇下一篇

猜你喜欢

热点阅读