gRPC code generation reference guide

Enabling gRPC code generation

默认情况下,位于 `src/main/proto`目录中的 `\*.proto`文件在构建过程中会被编译成 Java 源文件。

Using Maven

若要启用 gRPC 代码生成,请将以下依赖添加到项目:

<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-grpc</artifactId>
</dependency>

接下来,确保在 Quarkus Maven 插件中启用了 `generate-code`阶段:

<plugin>
    <groupId>${quarkus.platform.group-id}</groupId>
    <artifactId>quarkus-maven-plugin</artifactId>
    <version>${quarkus.platform.version}</version>
    <extensions>true</extensions>
    <executions>
        <execution>
            <goals>
                <goal>build</goal>
                <goal>generate-code</goal>
                <goal>generate-code-tests</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Using Gradle

对于 Gradle,将以下依赖添加到项目:

implementation 'io.quarkus:quarkus-grpc'

Customizing the proto directory

默认情况下,会假定 .proto` files are located in the src/main/proto directory. You can configure this location using the quarkus.grpc.codegen.proto-directory property in your *build descriptor

使用 Maven,添加以下配置:

<plugin>
    <groupId>${quarkus.platform.group-id}</groupId>
    <artifactId>quarkus-maven-plugin</artifactId>
    <version>${quarkus.platform.version}</version>
    <extensions>true</extensions>
    <executions>
        <execution>
            <goals>
                <goal>build</goal>
                <goal>generate-code</goal>
                <goal>generate-code-tests</goal>
            </goals>
            <configuration>
                <properties>
                    <quarkus.grpc.codegen.proto-directory>${project.basedir}/ext/proto</quarkus.grpc.codegen.proto-directory>
                </properties>
            </configuration>
        </execution>
    </executions>
</plugin>

使用 Gradle,使用以下配置:

quarkus {
    quarkusBuildProperties.put("quarkus.grpc.codegen.proto-directory", "${project.projectDir}/ext/proto")
}

Generating Descriptor Set

协议缓冲区不包含其自身的类型描述。因此,仅给定原始消息而没有定义其类型的对应 .proto 文件,则很难提取任何有用的数据。但是,.proto 文件的内容本身也可以是 represented using protocol buffers

默认情况下,Quarkus 不生成这些描述符。Quarkus 确实提供了用于生成它们的几个配置选项。这些选项将添加到 `application.properties`或 `application.yml`文件中:

  • quarkus.generate-code.grpc.descriptor-set.generate

    • 设置为 `true`以启用生成

  • quarkus.generate-code.grpc.descriptor-set.output-dir

    • 将其设为相对于项目构建目录的值(例如,Maven 的 target、Gradle 的 build

    • Maven default value: target/generated-sources/grpc

    • Gradle default value: $buildDir/classes/java/quarkus-generated-sources/grpc

  • quarkus.generate-code.grpc.descriptor-set.name

    • 要生成的描述符集文件的名称

    • Default value: descriptor_set.dsc

Configuring gRPC code generation for dependencies

在代码生成过程中,你可能会拥有包含 .proto files you want to compile to Java sources. This section explains how to configure code generation to include these \.proto 文件的依赖项。

Proto files for imports

Protocol Buffers 规范提供了一种办法来导入 proto 文件。Quarkus 代码生成机制允许你通过在 application.properties 中设置 quarkus.generate-code.grpc.scan-for-imports 属性来控制要扫描以查找可能导入项的依赖项范围。你可以将该属性设为以下某个值:

  • all——扫描所有依赖项

  • none——不扫描依赖项,仅使用 src/main/protosrc/test/proto 中定义的内容

  • groupId1:artifactId1,groupId2:artifactId2——仅按组 ID 和工件 ID 扫描指定依赖项。

如果未指定,则该属性默认为 com.google.protobuf:protobuf-java。要覆盖它,请在 application.properties 中设置 quarkus.generate-code.grpc.scan-for-imports 属性。例如:

quarkus.generate-code.grpc.scan-for-imports=all

Proto files from dependencies

在某些情况下,你可能希望从其他项目中使用 proto 文件来生成 gRPC 存根。要执行此操作:

  1. 在你的项目中添加对包含 proto 文件的工件的依赖项。

  2. application.properties 中,指定要扫描以查找 proto 文件的依赖项。

quarkus.generate-code.grpc.scan-for-proto=<groupId>:<artifactId>

该属性的值可以是 none(这是默认值),或由 groupId:artifactId 坐标分隔的逗号分隔列表。

如果依赖项包含许多 proto 文件,并且你仅想为其中一部分生成类,则可以为每个依赖项指定 glob 模式。要匹配的路径相对于依赖项中的 src/main/resources 路径。例如:

quarkus.generate-code.grpc.scan-for-proto-include."<groupId>:<artifactId>"=foo/**,bar/**,banana/a-proto.proto
quarkus.generate-code.grpc.scan-for-proto-exclude."<groupId>:<artifactId>"=foo/private/**,bar/another-proto.proto

请注意,属性键中的 : 字符必须进行转义。

Skipping code generation

你可以使用以下内容跳过 gRPC 代码生成:

  1. grpc.codegen.skip 系统属性: -Dgrpc.codegen.skip=true

  2. application.properties 文件中的 quarkus.grpc.codegen.skip 属性: quarkus.grpc.codegen.skip=true

Generating Java files from proto with the protobuf-maven-plugin

或者,要为 proto 文件生成存根,你可以使用 protobuf-maven-plugin。但是,建议使用 Quarkus 支持,除非你有特定需要。

若要执行此操作,请在 <properties> 部分中定义以下属性:

<grpc.version>{grpc-version}</grpc.version>
<protoc.version>{protoc-version}</protoc.version>

这些属性配置 gRPC 版本和 protoc 版本。

然后,将 os-maven-plugin 扩展和 protobuf-maven-plugin 配置添加到 build 部分:

<build>
    <extensions>
        <extension>
            <groupId>kr.motd.maven</groupId>
            <artifactId>os-maven-plugin</artifactId>
            <version>${os-maven-plugin-version}</version>
        </extension>
    </extensions>

    <plugins>
        <plugin>
            <groupId>org.xolstice.maven.plugins</groupId>
            <artifactId>protobuf-maven-plugin</artifactId>   (1)
            <version>${protobuf-maven-plugin-version}</version>
            <configuration>
                <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>  (2)
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
                <protocPlugins>
                    <protocPlugin>
                        <id>quarkus-grpc-protoc-plugin</id>
                        <groupId>io.quarkus</groupId>
                        <artifactId>quarkus-grpc-protoc-plugin</artifactId>
                        <version>{quarkus-version}</version>
                        <mainClass>io.quarkus.grpc.protoc.plugin.MutinyGrpcGenerator</mainClass>
                    </protocPlugin>
                </protocPlugins>
            </configuration>
            <executions>
                <execution>
                    <id>compile</id>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <goals>
                        <goal>test-compile</goal>
                        <goal>test-compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <!-- ... -->
    </plugins>
</build>
1 protobuf-maven-plugin 根据您的 gRPC 服务定义(proto 文件)生成存根类。
2 类生成使用特定的操作系统专用工具 protoc。这也是为什么我们使用 os-maven-plugin 将目标设置为与操作系统兼容的可执行文件的原因。

注意:此配置指示 protobuf-maven-plugin 使用 Mutiny 生成默认 gRPC 类和类,以适应 Quarkus 开发体验。

在使用 protobuf-maven-plugin 代替 quarkus-maven-plugin 时,需要在每次更新 proto 文件时重新生成类(使用 mvn compile)。

Using generated gRPC classes from dependencies

当从 proto 文件生成类的 gRPC 类在应用程序的依赖关系中时,依赖关系需要一个 Jandex 索引。您可以使用 jandex-maven-plugin 创建 Jandex 索引。有关此主题的更多信息,请参阅 CDI 指南的 Bean Discovery 部分。

<build>
    <plugins>
        <plugin>
            <groupId>io.smallrye</groupId>
            <artifactId>jandex-maven-plugin</artifactId>
            <version>{jandex-version}</version>
            <executions>
                <execution>
                <id>make-index</id>
                <goals>
                    <goal>jandex</goal>
                </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

如果您正在使用 Gradle,可以将以下配置用于:

plugins {
    id 'org.kordamp.gradle.jandex' version '1.1.0'
}

建议将 proto 文件打包到依赖关系中,而不是生成的类,这样 Quarkus 就可以生成优化的类。有关更多信息,请参阅 dedicated section

Argument files

protoc 命令行超出最大命令长度时,您可以要求 Quarkus 使用参数文件将参数传递到 protoc 命令。

若要启用此功能,请将 application.properties 文件中的 quarkus.generate-code.grpc.use-arg-file 属性设置为 true

如果您使用的是 Windows,并且命令行超过 8190 个字符,则 Quarkus 会自动使用参数文件将参数传递到 protoc 命令。