Skip to content

Commit 76f4153

Browse files
authored
gRPC Docs for the Initial Release (#263)
1 parent 335e4a6 commit 76f4153

File tree

7 files changed

+313
-4
lines changed

7 files changed

+313
-4
lines changed

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ permissions:
1414
env:
1515
INSTANCE: 'kotlinx-rpc/rpc'
1616
ARTIFACT: 'webHelpRPC2-all.zip'
17-
DOCKER_VERSION: '241.15989'
17+
DOCKER_VERSION: '243.22562'
1818
ALGOLIA_ARTIFACT: 'algolia-indexes-RPC.zip'
1919
ALGOLIA_APP_NAME: 'MMA5Z3JT91'
2020
ALGOLIA_INDEX_NAME: 'prod_kotlin_rpc'

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,18 @@ When using kRPC you only need to provide a transport or choose from the official
156156

157157
Besides that, one can even provide their own protocol or integration with one to use with services and `kotlinx.rpc` API with it.
158158
Though possible, it is much more complicated way to use the library and generally not needed.
159-
`kotlinx.rpc` aims to provide most common protocols integrations as well as the in-house one called kRPC.
160-
Integrations in progress:
161-
- Integration with [gRPC](https://grpc.io/) (in prototype)
159+
`kotlinx.rpc` aims to provide support for the most common protocol integrations, as well as the in-house protocol called kRPC.
160+
161+
## gRPC integration
162+
The library provides experimental support for the [gRPC](https://grop.io) protocol.
163+
The artifacts are published separately in our [Space repository](https://public.jetbrains.space/p/krpc/packages/maven/grpc).
164+
Current latest version:
165+
166+
![Dynamic XML Badge](https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fpublic%2Fp%2Fkrpc%2Fgrpc%2Forg%2Fjetbrains%2Fkotlinx%2Fkotlinx-rpc-core%2Fmaven-metadata.xml&query=%2F%2Fmetadata%2Fversioning%2Flatest&label=Latest%20dev%20version&color=forest-green&cacheSeconds=60)
167+
168+
For more information on gRPC usage,
169+
see the [official documentation](https://kotlin.github.io/kotlinx-rpc/grpc-configuration.html).
170+
For a working example, see the [sample gRPC project](/samples/grpc-app).
162171

163172
## Kotlin compatibility
164173
We support all stable Kotlin versions starting from 2.0.0:

docs/pages/kotlinx-rpc/rpc.tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
<toc-element topic="features.topic"/>
2626
<toc-element topic="transport.topic"/>
2727
</toc-element>
28+
<toc-element toc-title="gRPC">
29+
<toc-element topic="grpc-configuration.topic"/>
30+
<toc-element topic="grpc-services.topic"/>
31+
<toc-element topic="grpc-client.topic"/>
32+
<toc-element topic="grpc-server.topic"/>
33+
</toc-element>
2834
</toc-element>
2935
<toc-element topic="strict-mode.topic"/>
3036
<toc-element topic="versions.topic"/>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE topic
3+
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
4+
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
6+
title="Client" id="grpc-client">
7+
8+
<p>
9+
Example of using a gRPC client:
10+
</p>
11+
<code-block lang="Kotlin">
12+
val grpcClient = GrpcClient("localhost", 8080) {
13+
usePlaintext()
14+
}
15+
16+
val recognizer = grpcClient.withService&lt;ImageRecognizer&gt;()
17+
18+
val image = Image {
19+
data = byteArrayOf(0, 1, 2, 3)
20+
}
21+
val result = recognizer.recognize(image)
22+
println("Recognized category: ${result.category}")
23+
24+
grpcClient.cancel()
25+
</code-block>
26+
<list>
27+
<li>
28+
<code>usePlaintext()</code> - is a JVM binding to Java gRPC runtime. Other bindings are also present.
29+
</li>
30+
</list>
31+
</topic>
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE topic
3+
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
4+
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
6+
title="Configuration" id="grpc-configuration">
7+
8+
<tldr>
9+
<p>
10+
Artifacts for gRPC integration are published <a href="https://public.jetbrains.space/p/krpc/packages/maven/grpc">separately</a>
11+
and updated frequently, independent of the main releases.
12+
</p>
13+
<p>
14+
<a href="https://maven.pkg.jetbrains.space/public/p/krpc/grpc">
15+
<img alt="Latest dev version"
16+
src="https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fpublic%2Fp%2Fkrpc%2Fgrpc%2Forg%2Fjetbrains%2Fkotlinx%2Fkotlinx-rpc-core%2Fmaven-metadata.xml&amp;query=%2F%2Fmetadata%2Fversioning%2Flatest&amp;label=Latest%20dev%20version&amp;color=forest-green&amp;cacheSeconds=60"/>
17+
</a>
18+
</p>
19+
</tldr>
20+
21+
<p>
22+
<a href="https://grpc.io">gRPC</a> integration is available in an experimental state.
23+
The artifacts are published separately in our <a
24+
href="https://public.jetbrains.space/p/krpc/packages/maven/grpc">Space repository</a>.
25+
</p>
26+
<chapter title="Dependencies configuration" id="dependencies-configuration">
27+
<p>Below is an example of a project setup.</p>
28+
<code>settings.gradle.kts</code>:
29+
<code-block lang="Kotlin">
30+
pluginManagement {
31+
repositories {
32+
gradlePluginPortal()
33+
mavenCentral()
34+
maven("https://maven.pkg.jetbrains.space/public/p/krpc/grpc")
35+
}
36+
}
37+
</code-block>
38+
<p>
39+
<code>build.gradle.kts</code>:
40+
</p>
41+
<code-block lang="Kotlin">
42+
plugins {
43+
kotlin("jvm") version "2.1.0"
44+
kotlin("plugin.serialization") version "2.1.0"
45+
id("org.jetbrains.kotlinx.rpc.plugin") version "&lt;version&gt;"
46+
id("com.google.protobuf") version "0.9.4"
47+
}
48+
49+
repositories {
50+
mavenCentral()
51+
maven("https://maven.pkg.jetbrains.space/public/p/krpc/grpc")
52+
}
53+
54+
dependencies {
55+
implementation("org.jetbrains.kotlinx:kotlinx-rpc-grpc-core:&lt;version&gt;")
56+
implementation("ch.qos.logback:logback-classic:1.5.16")
57+
implementation("io.grpc:grpc-netty:1.69.0")
58+
}
59+
</code-block>
60+
<p>Here <code>&lt;version&gt;</code> comes from the badge above.</p>
61+
<warning>
62+
The setup has only been tested on <code>Kotlin/JVM</code> projects.
63+
</warning>
64+
</chapter>
65+
<chapter title="Protoc setup" id="protoc-setup">
66+
<p>
67+
gRPC requires additional code generation from the <a href="https://github.com/google/protobuf-gradle-plugin">protoc</a>
68+
compiler.
69+
This can be setup up in the following way:
70+
</p>
71+
<code-block lang="Kotlin">
72+
protobuf {
73+
protoc {
74+
artifact = "com.google.protobuf:protoc:4.29.3"
75+
}
76+
77+
plugins {
78+
create("kotlinx-rpc") {
79+
artifact = "org.jetbrains.kotlinx:kotlinx-rpc-protobuf-plugin:&lt;version&gt;:all@jar"
80+
}
81+
82+
create("grpc") {
83+
artifact = "io.grpc:protoc-gen-grpc-java:1.69.0"
84+
}
85+
86+
create("grpckt") {
87+
artifact = "io.grpc:protoc-gen-grpc-kotlin:1.4.1:jdk8@jar"
88+
}
89+
}
90+
91+
generateProtoTasks {
92+
all().all {
93+
plugins {
94+
create("kotlinx-rpc") {
95+
option("debugOutput=protobuf-plugin.log")
96+
option("messageMode=interface")
97+
}
98+
create("grpc")
99+
create("grpckt")
100+
}
101+
}
102+
}
103+
}
104+
</code-block>
105+
<list>
106+
<li>
107+
Four source sets will be generated:
108+
<list>
109+
<li><code>java</code> - protobuf Java declarations</li>
110+
<li><code>grpc</code> - gRPC Java declarations</li>
111+
<li><code>grpckt</code> - gRPC Kotlin wrappers for Java</li>
112+
<li><code>kotlinx-rpc</code> - pur wrappers for all of the above</li>
113+
</list>
114+
<p>
115+
You won't need to use the first three directly, only the declarations from the <code>kotlinx-rpc</code>
116+
source set are intended to be used.
117+
</p>
118+
Source sets are generated into <code>$BUILD_DIR/generated/source/proto/main</code> directory
119+
unless specified otherwise.
120+
</li>
121+
<li>
122+
<code>option("debugOutput=protobuf-plugin.log")</code> lets you specify the file
123+
for the <code>protoc</code> plugin debug output.
124+
</li>
125+
<li>
126+
<code>option("messageMode=interface")</code> is intended to be like so. Don't change it.
127+
</li>
128+
</list>
129+
</chapter>
130+
</topic>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE topic
3+
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
4+
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
6+
title="Server" id="grpc-server">
7+
8+
<p>
9+
Example of using a gRPC server:
10+
</p>
11+
<code-block lang="Kotlin">
12+
val grpcServer = GrpcServer(8080) {
13+
registerService&lt;ImageRecognizer&gt; { ImageRecognizerImpl() }
14+
}
15+
16+
grpcServer.start()
17+
grpcServer.awaitTermination()
18+
</code-block>
19+
<list>
20+
<li>
21+
<code>GrpcServer</code> allows to register multiple services, like regular <code>RpcServer</code>.
22+
However, <code>CoroutineContext</code> parameter is not needed and should not be used.
23+
</li>
24+
<li>
25+
<code>GrpcServer</code> does <b>not</b> bind to Java gRPC <code>Server</code>,
26+
but provides some functions to cover for that.
27+
</li>
28+
</list>
29+
</topic>
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE topic
3+
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
4+
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
6+
title="Services" id="grpc-services">
7+
8+
<p>
9+
To define a service, create a new <code>.proto</code> file in the <code>proto</code> folder next to your source sets:
10+
</p>
11+
<code-block>
12+
├── build.gradle.kts
13+
├── settings.gradle.kts
14+
└── src
15+
├── main
16+
│ ├── kotlin
17+
│ │ ├── Client.kt
18+
│ │ ├── ImageRecognizer.kt
19+
│ │ └── Server.kt
20+
│ └── resources
21+
│ └── logback.xml
22+
└── proto
23+
└── image-recognizer.proto
24+
</code-block>
25+
26+
<p>
27+
Inside the <code>.proto</code> file define your service:
28+
</p>
29+
<code-block lang="protobuf">
30+
syntax = "proto3";
31+
32+
message Image {
33+
bytes data = 1;
34+
}
35+
36+
message RecogniseResult {
37+
int32 category = 1;
38+
}
39+
40+
service ImageRecognizer {
41+
rpc recognize(Image) returns (RecogniseResult);
42+
}
43+
</code-block>
44+
<p>
45+
This will generate the necessary code, including the most important interfaces:
46+
<code>ImageRecognizer</code>, <code>Image</code>, <code>RecogniseResult</code>:
47+
</p>
48+
<code-block lang="Kotlin">
49+
@Grpc
50+
interface ImageRecognizer {
51+
suspend fun recognize(image: Image): RecogniseResult
52+
}
53+
54+
interface RecogniseResult {
55+
val category: Int
56+
57+
companion object
58+
}
59+
60+
interface Image {
61+
val data: ByteArray
62+
63+
companion object
64+
}
65+
</code-block>
66+
<p>
67+
You can implement the <code>ImageRecognizer</code>:
68+
</p>
69+
<code-block lang="Kotlin">
70+
class ImageRecognizerImpl : ImageRecognizer {
71+
override suspend fun recognize(image: Image): RecogniseResult {
72+
val byte = image.data[0].toInt()
73+
delay(100) // heavy processing
74+
val result = RecogniseResult {
75+
category = if (byte == 0) 0 else 1
76+
}
77+
return result
78+
}
79+
}
80+
</code-block>
81+
<p>
82+
Here you can also see the usage of the <code>RecogniseResult</code> interface.
83+
To create an instance, use its <code>.invoke()</code> extension function:
84+
</p>
85+
<code-block lang="Kotlin">
86+
RecogniseResult {
87+
category = 0
88+
}
89+
</code-block>
90+
91+
<chapter title="Limitations" id="limitations">
92+
<p>Current known limitations:</p>
93+
<list>
94+
<li>No streaming</li>
95+
<li>Only primitive types in messages</li>
96+
<li>Mandatory java and kotlin protoc generation in addition to our codegen</li>
97+
<li>Kotlin/JVM project only</li>
98+
</list>
99+
<p>
100+
If you encounter other unexpected limitations or bugs,
101+
please <a href="https://github.com/Kotlin/kotlinx-rpc/issues/new?template=bug_report.md">report</a> them
102+
</p>
103+
</chapter>
104+
</topic>

0 commit comments

Comments
 (0)