利用goctl生成rpc服务
- 编写proto文件
// 声明 proto 使用的语法版本
syntax = "proto3";// proto 包名
package demoRpc;// golang 包名(可选)
option go_package = "./demo";// 如需为 .proto 文件添加注释,请使用 C/C++ 样式的 // 和 /* ... */ 语法。
/* SearchRequest represents a search query, with pagination options to* indicate which results to include in the response. */// 支持import 引入其他.proto文件 但是要求较多,没有.api文件容易简易
// 好像是service必须在主文件,引入的proto文件只能包含message定义
import "***.proto";// 枚举
// 在定义消息类型时,您可能希望它的某个字段仅具有一个预定义的值列表。例如,假设您想要为每个
// SearchRequest 添加一个 corpus 字段,其中正文可以是 UNIVERSAL、WEB、IMAGES、LOCAL、
// NEWS、PRODUCTS 或 VIDEO。为此,您只需在消息定义中添加 enum 并针对每个可能的值添加一个常量。// 在以下示例中,我们添加了一个名为 Corpus 的 enum(包含所有可能的值)和 Corpus 类型的字段:
// 如您所见,Corpus 枚举的第一个常量映射到零:每个枚举定义必须包含一个映射到零的第一个常量作为其
// 第一个元素。原因如下:
//
// 1. 必须有一个零值,以便我们可以使用 0 作为数字的默认值。
// 2/ 零值必须是第一个元素,以便与 proto2 语义(其中第一个枚举值始终是默认值)兼容。enum Corpus {CORPUS_UNSPECIFIED = 0;CORPUS_UNIVERSAL = 1;CORPUS_WEB = 2;CORPUS_IMAGES = 3;CORPUS_LOCAL = 4;CORPUS_NEWS = 5;CORPUS_PRODUCTS = 6;CORPUS_VIDEO = 7;
}// 结构体
// SearchRequest 消息定义指定三个字段(名称/值对),每个字段对应于要包含在此类消息中的每段数据。每个字段都有一个名称和类型。
// 类型可以指包括基本类型,切片用 repeated 数据类型 表示,也支持map<数据类型,数据类型>, 以及自定义数据类型
// 字段默认是可选的
message SearchRequest {string query = 1;int32 page_number = 2;int32 result_per_page = 3;Corpus corpus = 4;repeated Result results = 6;map<string, string> projects = 8;
}message Result {string url = 1;string title = 2;repeated string snippets = 3;
}message SearchResponse {map<string, int32> projects = 1;
}// 保留字段编写示例 不重要 保留————》在这个结构体中这几个字段不能再被使用
// 如果您通过完全移除或注释掉某个字段来更新消息类型,则将来的用户可以自行更新该字段编号以对
// 该类型进行更新。如果用户日后加载同一 .proto 的旧版本(包括数据损坏、隐私 bug 等),
// 这可能会导致严重问题。确保不会发生这种情况的一种方法是,指定已删除字段的字段编号
// (和/或名称,也可能导致 JSON 序列化问题)为 reserved。如果任何未来用户尝试使用这些字
// 段标识符,协议缓冲区编译器就会抱怨。
message Foo {reserved 2, 15, 9 to 11;reserved "foo", "bar";
}// 定义服务
// 如果在goctl命令中不设置 -m 则一个文件proto文件中只能有一个 service 多个 service 会报错
// 但是由于import 不好用,且项目上需要分组, 可以编写多个 service 这样切记执行命令时增加 -m
service Demo {// 普通的rpc定义 rpc 方法名称(请求体)returns (响应体);rpc Search(SearchRequest) returns (SearchResponse);// 客户端流rpc ClientStream(stream SearchRequest) returns (SearchResponse);// 服务端流rpc ServerStream(SearchRequest) returns (stream SearchResponse);// 双向流rpc TwoStream(stream SearchRequest) returns (stream SearchResponse);
}
- 执行goctl命令
goctl rpc protoc xxx.proto --go_out=. --go-grpc_out=. --zrpc_out=. (-m 服务分组时)
-
执行结果
其中:
etc:静态配置文件目录
demo.go:程序启动入口文件
internal:单个服务内部文件,其可见范围仅限当前服务
config:静态配置文件对应的结构体声明目录
logic:业务目录,所有业务编码文件都存放在这个目录下面,logic 为固定后缀
server:类似于API中的handle层,无需修改
svc:依赖注入目录,所有 logic 层需要用到的依赖都要在这里进行显式注入
democlient:客户端调用服务端rpc相关代码
pb文件:简单理解为API中的type文件,还包括其他一些代码,在服务端和客户端都需要调用 -
接下来你只需要负责logic的具体实现就可以了,当前你也可以对生成的内容进行修改