Skip to content

Latest commit

 

History

History
248 lines (191 loc) · 7.97 KB

3.protobuf_stub_plugin.md

File metadata and controls

248 lines (191 loc) · 7.97 KB

生成tRPC-Java 桩代码

桩代码是用于定义RPC服务的API以及相关数据格式的代码。tRPC使用protobuf来定义服务API与数据格式,tRPC-Java则提供maven插件来实现以protobuf 描述文件(.proto)生成Java桩代码。

trpc-maven-plugin

功能列表:

  1. 生成tRPC桩代码,由两部分组成:
    1. protobuf数据协议代码
    2. tRPC服务接口(Java interface)
  2. 生成Validator代码(由protoc-gen-validate生成)
  3. 生成pom.xml文件,包含桩代码所需的依赖

环境需求

  • maven 3.6.3+

基本使用

引入Maven插件

在pom.xml中定义:

<build>
    <plugins>
        <plugin>
            <groupId>com.tencent.trpc</groupId>
            <artifactId>trpc-maven-plugin</artifactId>
            <!-- see version https://github.com/trpc-group/trpc-java/releases -->
            <version>1.0.0</version>
        </plugin>
    </plugins>
</build>

需注意,多module项目中,需要在子module的pom.xml中引入上述插件

编写API描述文件(.proto文件)

插件默认读取直接位于src/main/proto目录下的.proto文件,子目录中的*.proto文件则被视为依赖。也就是说,src/main/proto/ 下的proto文件可以import src/main/proto/{any_sub_dir}下的proto文件。但需要注意,引用时需使用相对路径。

默认的proto源文件目录可以通过参数protoSourceRoot来自定义,具体见文尾的参数说明部分

具体的protobuf文件语法,请参考protobuf官方文档 。下面以 trpc-java-demo 演示如何使用这个插件,proto文件示例如下:

syntax = "proto3";

package trpc.TestApp.TestServer;

option java_package = "com.tencent.trpc.demo.proto";  // 设定桩代码文件的java package
option java_outer_classname = "HelloRequestProtocol"; // 将多个protobuf协议类封装到设定的包装类中

// If do not customize url, no need to import the next proto file.
import "trpc.proto";

// 定义数据结构

message HelloRequest {
  string message = 1;
}

message HelloResponse {
  string message = 1;
}

// 定义API

// Normal service
service GreeterService {
  rpc sayHello (HelloRequest) returns (HelloResponse) {}
}

// Normal service with customized url
service GreeterService2 {
  rpc sayHi (HelloRequest) returns (HelloResponse) {
    option (trpc.alias) = "/api/hi";
  }
}

// Stream service
service StreamGreeterService {
  rpc clientSayHellos (stream HelloRequest) returns (HelloResponse) {}
  rpc serverSayHellos (HelloRequest) returns (stream HelloResponse) {}
  rpc allSayHellos (stream HelloRequest) returns (stream HelloResponse) {}
}

执行Maven插件

插件对应的maven goal是gen-code,即通过下面命令可以调用插件生成代码:

// trpc-java-demo 为例,执行代码
git clone https://github.com/trpc-group/trpc-java.git
cd trpc-java
mvn -Dmaven.test.skip=true clean install
cd trpc-demo/trpc-java-demo
mvn trpc:gen-code

也可以根据需要将插件goal绑定至其他maven phase:

<build>
    <plugins>
        <plugin>
            <groupId>com.tencent.trpc</groupId>
            <artifactId>trpc-maven-plugin</artifactId>
            <version>1.0.0</version>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>gen-code</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

收集生成的桩代码

插件默认的输出目录是target/generated-sources/trpc/java/

默认的输出目录可以通过参数outputDirectory来自定义,具体见文尾的参数说明部分

以前文中的.proto文件样例为例,生成的桩代码文件结构如下:

target/generated-sources/trpc/java/com/tencent/trpc/demo/proto
├── GreeterService2API.java
├── GreeterService2AsyncAPI.java
├── GreeterServiceAPI.java
├── GreeterServiceAsyncAPI.java
├── HelloRequestProtocol.java
├── StreamGreeterServiceAPI.java
├── StreamGreeterServiceAsyncAPI.java
└── StreamGreeterServiceStreamAPI.java

生成的代码文件包含两类

  1. tRPC-Java API接口类,以.proto文件中的service名称 + 固定后缀命名:
    1. API.java后缀,代表普通的同步API
    2. AsyncAPI.java后缀,代表异步API
    3. StreamAPI.java后缀,代表流式API
  2. protobuf 协议类,根据.proto文件的定义,可能是每个message对应一个类,也可能是都包装在一个类中。协议类代码的生成由插件代理至protoc实现

进阶用法

定义接口alias

可通过在.proto文件中为rpc设置option(trpc.alias)来实现设置tRPC接口的alias:

syntax = "proto3";
...
import "trpc.proto"; // 引用trpc.proto以激活trpc.alias option,trpc.proto会由trpc-maven-plugin内置,无需额外配置
...
service Greeter {
  rpc SayHello (stream HelloRequest) returns (stream HelloReply) { option(trpc.alias) = "/api/helloworld"; }
}
...

关于protoc

trpc-maven-plugin依赖protoc可执行文件生成protobuf桩代码。

通常情况下用户不需要关心,插件会根据当前操作系统类型,从maven远程仓库下载预编译的protoc二进制文件。

如果插件的默认行为不能满足需求(比如protoc没有发布对应你的操作系统的预编译二进制文件,或你需要特定版本的protoc),插件也支持调用编译环境中现有的protoc 可执行文件,通过插件参数<protocExecutable>设置本地protoc命令即可:

<build>
    <plugins>
        <plugin>
            <groupId>com.tencent.trpc</groupId>
            <artifactId>trpc-maven-plugin</artifactId>
            <version>1.0.0</version> 
            <configuration>
                <protocExecutable>protoc</protocExecutable>
            </configuration>
        </plugin>
    </plugins>
</build>

关于数据校验代码

trpc-maven-plugin支持生成数据校验代码:

syntax = "proto3";
...
import "validate.proto"; // 依赖的validate.proto会由trpc-maven-plugin提供,无需额外配置
...
message HelloRequest {
  string message = 1 [(validate.rules).string.min_len = 2]; // 定义字段校验规则
  int64 ts = 2;
}
...

校验代码的生成由protoc-gen-validate实现。与protoc可执行文件类似,插件会根据操作系统自动下载预编译的protoc-gen-validate,通常情况下不需要关心。

也可以自行指定本地的protoc-gen-validate可执行文件文件:

<build>
    <plugins>
        <plugin>
            <groupId>com.tencent.trpc</groupId>
            <artifactId>trpc-maven-plugin</artifactId>
            <version>1.0.0</version>
            <configuration>
                <pgvPluginExecutable>protoc-gen-validate</pgvPluginExecutable>
            </configuration>
        </plugin>
    </plugins>
</build>

插件参数说明

可以通过调整参数改变插件默认行为

参数列表:

参数名 说明 默认值
protoSourceRoot .proto源文件目录 ${basedir}/src/main/proto
outputDirectory 生成代码文件的输出目录 ${project.build.directory}/generated-sources/trpc/java
protocExecutable 本地protoc执行命令 null (从maven远程仓库获取预编译文件)
pgvPluginExecutable 本地protoc-gen-validate执行命令 null (从maven远程仓库获取预编译文件)
osClassifier 操作系统识别符(如linux-x86_64),用于匹配预编译protoc文件 自动识别。设置此参数后会覆盖自动识别出的值
noPom 不生成pom.xml文件 false
customTemplates 额外的自定义代码模板 null
codeGeneratorHookClass com.tencent.trpc.codegen.TRpcCodeGeneratorHook的实现类类全名,和customTemplates组合使用可以实现定制化代码生成。具体用法请见相关类的javadoc,以及此例子 null