diff --git a/docs/pages/kotlinx-rpc/topics/grpc-configuration.topic b/docs/pages/kotlinx-rpc/topics/grpc-configuration.topic index aba2cfd5..92783b63 100644 --- a/docs/pages/kotlinx-rpc/topics/grpc-configuration.topic +++ b/docs/pages/kotlinx-rpc/topics/grpc-configuration.topic @@ -1,4 +1,8 @@ + +

- Artifacts for gRPC integration are published separately + Artifacts for gRPC integration are published separately and updated frequently, independent of the main releases.

@@ -39,137 +44,427 @@ build.gradle.kts:

- plugins { - kotlin("jvm") version "%kotlin-version%" - kotlin("plugin.serialization") version "%kotlin-version%" - id("org.jetbrains.kotlinx.rpc.plugin") version "<version>" - id("com.google.protobuf") version "0.9.4" - } - - repositories { - mavenCentral() - maven("https://maven.pkg.jetbrains.space/public/p/krpc/grpc") - } - - dependencies { - implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-core:<version>") - implementation("ch.qos.logback:logback-classic:1.5.16") - implementation("io.grpc:grpc-netty:1.69.0") - } + plugins { + kotlin("jvm") version "%kotlin-version%" + id("org.jetbrains.kotlinx.rpc.plugin") version "<version>" + } + + repositories { + mavenCentral() + maven("https://maven.pkg.jetbrains.space/public/p/krpc/grpc") + } + + dependencies { + implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-core:<version>") + implementation("ch.qos.logback:logback-classic:1.5.16") + implementation("io.grpc:grpc-netty:1.73.0") + }

Here <version> comes from the badge above.

- - The setup has only been tested on Kotlin/JVM projects. - + + We prohibit using com.google.protobuf Gradle Plugin + in projects with our plugin to prevent conflicts. + - + + + Working with proto-files +

- gRPC requires additional code generation from the protoc - compiler. - It is set up automatically for you when the com.google.protobuf - plugin is present in the project. + The minimum required configuration looks like this:

+ + rpc { + grpc() + } +

- We provide additional options for configuration: + This enables code generation for your .proto files. + Special source sets are created for them: +

+ +
  • + main and test - source sets for Kotlin/JVM projects. + Default source directories are src/main/proto and src/test/proto. +
  • +
  • + jvmMain and jvmTest - source sets for Kotlin/Multiplatform projects. + Default source directories are src/jsmMain/proto and src/jvmTest/proto. + + These will change to src/commonMain/proto and src/commonTest/proto in the + future. + +
  • +
  • + Android source set support is not available yet but will be included in a future release. +
  • +
    +

    + All source sets are generated automatically and available + via the protoSourceSets Gradle Project extension:

    - rpc { - grpc { - // Enforce additional checks on the project configuration - enabled = true - - // Quick access to a `Locator` and `Options` - // for the kotlinx-rpc Protobuf plugin - plugin { - options { - // Add or modify options - option("debugOutput=myFile.txt") - } - - locator { - // Override artifact coordinates - artifact = "some-other:artifact:version" - } + protoSourceSets { + // for Kotlin/JVM projects + main { + proto { + // SourceDirectorySet for .proto files + include("**/main.proto") // optional filters + exclude("**/excluded.proto") } + } + test { } - // same as `plugin`, but for gRPC Java generation - grpcJavaPlugin { ... } - // same as `plugin`, but for gRPC Kotlin generation - grpcKotlinPlugin { ... } - - // access `generateProto` tasks - tasks { - plugins { - create("python") - } - } + // for Kotlin/Multiplatform projects + jvmMain { } + jvmTest { } + } + +

    + By default, the following source directories are generated: +

    + +
  • + java - protobuf Java declarations, attached to java sources. +
  • +
  • + grpc-java - gRPC Java declarations, attached to java sources. +
  • +
  • + grpc-kotlin - gRPC Kotlin wrappers for Java, attached to kotlin sources. +
  • +
  • + kotlin-multiplatform - wrappers for all of the above, attached to kotlin sources. +
  • +
    + + Only the declarations from the kotlin-multiplatform source set are intended to be used. + The others are for internal use only and will be removed in a future release. + +
    + +

    + Source set hierarchy is not supported, and we have no plans to support it. + That means, for example, + that you can't have jsMain and jsTest source sets for proto files. + The same applies for native and Wasm targets. + Currently, .proto files are only supported in the jvmMain and jvmTest source sets. + (Later to be replaced with commonMain and commonTest) +
    +
    + If you have a use case for other source sets and a hierarchy, + please report it. +

    +
    + +

    + To generate code, we use protoc plugins. + By default, we use the following plugins: +

    + +
  • + protobuf-java - Buf's version of the official Java + plugin. +
  • +
  • + grpc-java - Buf's version of the official gRPC Java plugin. +
  • +
  • + grpc-kotlin - Buf's version of the official gRPC Kotlin + plugin. +
  • +
  • + kotlin-multiplatform - out own protoc plugin. +
  • +
    +

    + You can configure the plugins in the rpc block: +

    + + rpc { + grpc { + // configure plugins here + protocPlugins { + kotlinMultiplatform { } + protobufJava { } + grpcJava { } + grpcKotlin { } - // access `generateProto` tasks with a filter - tasksMatching { it.isTest }.all { - plugins { - create("cpp") - } + create("myPlugin") { } } } }

    - You can still use protobuf extension to access the configuration. - The following is the equivalent for the above code using the protobuf extension: + protocPlugins is a NamedDomainObjectContainer<ProtocPlugin>, + which allows you to add your own plugins. +

    +

    + Each plugin is represented by a ProtocPlugin and can be configured like this:

    - protobuf { - plugins { - named(GrpcExtension.LOCATOR_NAME) { - artifact = "some-other:artifact:version" - } + // Or use protocPlugins.kotlinMultiplatform for default plugins + protocPlugins.create("myPlugin") { + isJava = true // add generated code to the java source set - named(GrpcExtension.GRPC_JAVA_LOCATOR_NAME) { ... } - named(GrpcExtension.GRPC_KOTLIN_LOCATOR_NAME) { ... } - } + // Add plugin options + options.put("myOption") + options.put("myOption1", "myValue") - generateProtoTasks { - all().all { - plugins { - named(GrpcExtension.LOCATOR_NAME) { - option("debugOutput=myFile.txt") - } + // Plugin can be local or remote - create("python") + // For a local plugin + local { + // Path to the plugin executable + executor("java", "-jar", "myPlugin.jar") + // or + javaJar("myPlugin.jar") // uses java.home + // or + javaJar("myPlugin.jar", "path/to/my/java") + // or + executor("myCustomExe.exe") + } - if (isTest) { - create("cpp") - } - } - } + // For a remote plugin + remote { + // Buf's BSR locator + locator = "buf.build/grpc/go" } + + // Additional Buf configuration options: + strategy = ProtocPlugin.Strategy.All + includeImports = false + includeWkt = false + types = listOf("my.package.MyType") + excludeTypes = listOf("my.package.NotMyType") }

    - The minimum recommended configuration looks like this: + Buf's plugin configuration + options: +

    + + + strategy + — All or Directory + + + includeImports + — true or false + + + includeWkt + — true or false + + + types + — a list of types to generate. + + + excludeTypes + — a list of types to exclude from generation. + + +

    + Once a plugin is added to the protocPlugins container, it can be used in a source set:

    - rpc { - grpc { - enabled = true + protoSourceSets { + jvmMain { + protocPlugin(rpc.grpc.protocPlugins.named("myPlugin")) } } +
    +

    - By default, four source sets will be generated: -

    - -
  • java - protobuf Java declarations
  • -
  • grpc - gRPC Java declarations
  • -
  • grpckt - gRPC Kotlin wrappers for Java
  • -
  • kotlinx-rpc - our wrappers for all of the above
  • -
    -

    - Only the declarations from the kotlinx-rpc source set are intended to be used. -

    -

    - Source sets are generated into the $BUILD_DIR/generated/source/proto/main directory - unless specified otherwise. + As you may already notice, + we use Buf — + a tool for managing and building Protobuf schemas. + We use its CLI to execute tasks like code generation.

    + + We don't use Buf's build.buf Gradle Plugin + and disallow using it in projects that apply our plugin, in order to avoid conflicts. + + +

    + To improve the developer experience, we introduce the concept of a generated workspace. + It's a directory that contains all the necessary files for Buf to work: +

    + +
  • + Filtered .proto files +
  • +
  • + Generated buf.yaml file +
  • +
  • + Generated buf.gen.yaml file +
  • +
  • + Automatically managed imports from a main source set to a test source set, + making imports intuitive. +
  • +
    +

    + This workspace is created automatically for each source set + and can be found in the build/protoBuild directory. + You don't need to do anything with it, unless you want to customize it. +

    +
    + +

    + If your project is configured to use gRPC, the following tasks will be generated: +

    + +
  • + generateBufYaml<sourceSet> + — generates buf.yaml +
    +
    + Type: kotlinx.rpc.buf.tasks.GenerateBufYaml +
  • +
  • + generateBufGenYaml<sourceSet> + — generates buf.gen.yaml +
    +
    + Type: kotlinx.rpc.buf.tasks.GenerateBufGenYaml +
  • +
  • + processProtoFiles<sourceSet> + — copies proto files to the workspace directory +
    +
    + Type: kotlinx.rpc.proto.ProcessProtoFiles +
  • +
  • + processProtoFilesImport<sourceSet> + — copies import proto files to the workspace directory +
    +
    + Type: kotlinx.rpc.proto.ProcessProtoFiles +
  • +
  • + bufGenerate<sourceSet> + — runs buf generate command. +
    +
    + Type: kotlinx.rpc.buf.tasks.BufGenerateTask +
  • +
    +

    + To configure Buf, use the buf block: +

    + + rpc { + grpc { + buf { + // Configure Buf + logFormat = BufExtenstion.LogFormat.Text + timeout = 60.seconds + + generate { + // Configure Buf generate + + includeImports = false + includeWkt = false + errorFormat = BufGenerateExtenstion.ErrorFormat.Text + } + } + } + } + +

    + General configuration options: +

    + + + logFormat + — either Text, Color, Json or Default + + + timeout + — timeout for the buf commands, always converted to whole seconds + + + Running Gradle with --debug enables Buf's --debug option as well. + + +

    + buf generate configuration options: +

    + + + includeImports + — true or false + + + includeWkt + — true or false + + + errorFormat + — either Text, Json, Msvs, + Junit, GithubActions or Default + + +
    + +

    + Currently, we only support generate tasks. + However, because of Buf's capabilities for managing .proto files, + like linting and detection of breaking changes, + we provide a way to create custom Buf tasks. +

    +

    + To create a custom task, extend the kotlinx.rpc.buf.tasks.BufExecTask class. + You don't need to define a @TaskAction; just a set of arguments and a command to execute. +

    +

    + You can register the task in two ways: +

    + +
  • +

    A workspace task (recommended):

    + + rpc.grpc.buf.tasks { + val provider = registerWorkspaceTask<MyBufLintTask>("lint") { + // configure task here + } + + // bufLintMain, or bufLintJvmMain for KMP projects + provider.mainTask + + // bufLintTest, or bufLintJvmTest for KMP projects + provider.testTask + } + +

    + These tasks can be executed on a generated workspace for all proto source sets. +

    + + These tasks are not plugged into the Gradle build cycle, + so you must run them manually + +
  • +
  • +

    A regular task:

    + + project.registerBufExecTask<MyBufLintTask>( + name = "bufLint", + workingDir = workingDirProvider, + ) { + // configure task here + } + +

    + It is a standard Gradle task that has access to the Buf's executable + and some predefined properties. +

    +
  • +
    +