-
Notifications
You must be signed in to change notification settings - Fork 40
gRPC Docs for the Initial Release #263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE topic | ||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd"> | ||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd" | ||
title="Client" id="grpc-client"> | ||
|
||
<p> | ||
Example of using a gRPC client: | ||
</p> | ||
<code-block lang="Kotlin"> | ||
val grpcClient = GrpcClient("localhost", 8080) { | ||
usePlaintext() | ||
} | ||
|
||
val recognizer = grpcClient.withService<ImageRecognizer>() | ||
|
||
val image = Image { | ||
data = byteArrayOf(0, 1, 2, 3) | ||
} | ||
val result = recognizer.recognize(image) | ||
println("Recognized category: ${result.category}") | ||
|
||
grpcClient.cancel() | ||
</code-block> | ||
<list> | ||
<li> | ||
<code>usePlaintext()</code> - is a JVM binding to Java gRPC runtime. Other bindings are also present. | ||
</li> | ||
</list> | ||
</topic> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE topic | ||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd"> | ||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd" | ||
title="Configuration" id="grpc-configuration"> | ||
|
||
<tldr> | ||
<p> | ||
Artifacts for gRPC integration are published <a href="https://public.jetbrains.space/p/krpc/packages/maven/grpc">separately</a> | ||
and updated frequently, independent of the main releases. | ||
</p> | ||
<p> | ||
<a href="https://maven.pkg.jetbrains.space/public/p/krpc/grpc"> | ||
<img alt="Latest dev version" | ||
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&query=%2F%2Fmetadata%2Fversioning%2Flatest&label=Latest%20dev%20version&color=forest-green&cacheSeconds=60"/> | ||
</a> | ||
</p> | ||
</tldr> | ||
|
||
<p> | ||
<a href="https://grpc.io">gRPC</a> integration is available in an experimental state. | ||
The artifacts are published separately in our <a | ||
href="https://public.jetbrains.space/p/krpc/packages/maven/grpc">Space repository</a>. | ||
</p> | ||
<chapter title="Dependencies configuration" id="dependencies-configuration"> | ||
<p>Below is an example of a project setup.</p> | ||
<code>settings.gradle.kts</code>: | ||
<code-block lang="Kotlin"> | ||
pluginManagement { | ||
repositories { | ||
gradlePluginPortal() | ||
mavenCentral() | ||
maven("https://maven.pkg.jetbrains.space/public/p/krpc/grpc") | ||
} | ||
} | ||
</code-block> | ||
<p> | ||
<code>build.gradle.kts</code>: | ||
</p> | ||
<code-block lang="Kotlin"> | ||
plugins { | ||
kotlin("jvm") version "2.1.0" | ||
kotlin("plugin.serialization") version "2.1.0" | ||
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") | ||
} | ||
</code-block> | ||
<p>Here <code><version></code> comes from the badge above.</p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be removed if you replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
<warning> | ||
The setup has only been tested on <code>Kotlin/JVM</code> projects. | ||
</warning> | ||
</chapter> | ||
<chapter title="Protoc setup" id="protoc-setup"> | ||
<p> | ||
gRPC requires additional code generation from the <a href="https://github.com/google/protobuf-gradle-plugin">protoc</a> | ||
compiler. | ||
This can be setup up in the following way: | ||
</p> | ||
<code-block lang="Kotlin"> | ||
protobuf { | ||
protoc { | ||
artifact = "com.google.protobuf:protoc:4.29.3" | ||
} | ||
|
||
plugins { | ||
create("kotlinx-rpc") { | ||
artifact = "org.jetbrains.kotlinx:kotlinx-rpc-protobuf-plugin:<version>:all@jar" | ||
} | ||
|
||
create("grpc") { | ||
artifact = "io.grpc:protoc-gen-grpc-java:1.69.0" | ||
} | ||
|
||
create("grpckt") { | ||
artifact = "io.grpc:protoc-gen-grpc-kotlin:1.4.1:jdk8@jar" | ||
} | ||
} | ||
|
||
generateProtoTasks { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be nice to explain what this configuration does after the code block. |
||
all().all { | ||
plugins { | ||
create("kotlinx-rpc") { | ||
option("debugOutput=protobuf-plugin.log") | ||
option("messageMode=interface") | ||
} | ||
create("grpc") | ||
create("grpckt") | ||
} | ||
} | ||
} | ||
} | ||
</code-block> | ||
<list> | ||
<li> | ||
Four source sets will be generated: | ||
<list> | ||
<li><code>java</code> - protobuf Java declarations</li> | ||
<li><code>grpc</code> - gRPC Java declarations</li> | ||
<li><code>grpckt</code> - gRPC Kotlin wrappers for Java</li> | ||
<li><code>kotlinx-rpc</code> - pur wrappers for all of the above</li> | ||
</list> | ||
<p> | ||
You won't need to use the first three directly, only the declarations from the <code>kotlinx-rpc</code> | ||
source set are intended to be used. | ||
</p> | ||
Source sets are generated into <code>$BUILD_DIR/generated/source/proto/main</code> directory | ||
unless specified otherwise. | ||
</li> | ||
<li> | ||
<code>option("debugOutput=protobuf-plugin.log")</code> lets you specify the file | ||
for the <code>protoc</code> plugin debug output. | ||
</li> | ||
<li> | ||
<code>option("messageMode=interface")</code> is intended to be like so. Don't change it. | ||
</li> | ||
</list> | ||
</chapter> | ||
</topic> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE topic | ||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd"> | ||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd" | ||
title="Server" id="grpc-server"> | ||
|
||
<p> | ||
Example of using a gRPC server: | ||
</p> | ||
<code-block lang="Kotlin"> | ||
val grpcServer = GrpcServer(8080) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here it would also be nice to explain what each line does, for example with bullet points after the code block. |
||
registerService<ImageRecognizer> { ImageRecognizerImpl() } | ||
} | ||
|
||
grpcServer.start() | ||
grpcServer.awaitTermination() | ||
</code-block> | ||
<list> | ||
<li> | ||
<code>GrpcServer</code> allows to register multiple services, like regular <code>RpcServer</code>. | ||
However, <code>CoroutineContext</code> parameter is not needed and should not be used. | ||
</li> | ||
<li> | ||
<code>GrpcServer</code> does <b>not</b> bind to Java gRPC <code>Server</code>, | ||
but provides some functions to cover for that. | ||
</li> | ||
</list> | ||
</topic> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE topic | ||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd"> | ||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd" | ||
title="Services" id="grpc-services"> | ||
|
||
<p> | ||
To define a service, create a new <code>.proto</code> file in the <code>proto</code> folder next to your source sets: | ||
</p> | ||
<code-block> | ||
├── build.gradle.kts | ||
├── settings.gradle.kts | ||
└── src | ||
├── main | ||
│ ├── kotlin | ||
│ │ ├── Client.kt | ||
│ │ ├── ImageRecognizer.kt | ||
│ │ └── Server.kt | ||
│ └── resources | ||
│ └── logback.xml | ||
└── proto | ||
└── image-recognizer.proto | ||
</code-block> | ||
|
||
<p> | ||
Inside the <code>.proto</code> file define your service: | ||
</p> | ||
<code-block lang="protobuf"> | ||
syntax = "proto3"; | ||
|
||
message Image { | ||
bytes data = 1; | ||
} | ||
|
||
message RecogniseResult { | ||
int32 category = 1; | ||
} | ||
|
||
service ImageRecognizer { | ||
rpc recognize(Image) returns (RecogniseResult); | ||
} | ||
</code-block> | ||
<p> | ||
This will generate the necessary code, including the most important interfaces: | ||
<code>ImageRecognizer</code>, <code>Image</code>, <code>RecogniseResult</code>: | ||
</p> | ||
<code-block lang="Kotlin"> | ||
@Grpc | ||
interface ImageRecognizer { | ||
suspend fun recognize(image: Image): RecogniseResult | ||
} | ||
|
||
interface RecogniseResult { | ||
val category: Int | ||
|
||
companion object | ||
} | ||
|
||
interface Image { | ||
val data: ByteArray | ||
|
||
companion object | ||
} | ||
</code-block> | ||
<p> | ||
You can implement the <code>ImageRecognizer</code>: | ||
</p> | ||
<code-block lang="Kotlin"> | ||
class ImageRecognizerImpl : ImageRecognizer { | ||
override suspend fun recognize(image: Image): RecogniseResult { | ||
val byte = image.data[0].toInt() | ||
delay(100) // heavy processing | ||
val result = RecogniseResult { | ||
category = if (byte == 0) 0 else 1 | ||
} | ||
return result | ||
} | ||
} | ||
</code-block> | ||
<p> | ||
Here you can also see the usage of the <code>RecogniseResult</code> interface. | ||
To create an instance, use its <code>.invoke()</code> extension function: | ||
</p> | ||
<code-block lang="Kotlin"> | ||
RecogniseResult { | ||
category = 0 | ||
} | ||
</code-block> | ||
|
||
<chapter title="Limitations" id="limitations"> | ||
<p>Current known limitations:</p> | ||
<list> | ||
<li>No streaming</li> | ||
<li>Only primitive types in messages</li> | ||
<li>Mandatory java and kotlin protoc generation in addition to our codegen</li> | ||
<li>Kotlin/JVM project only</li> | ||
</list> | ||
<p> | ||
If you encounter other unexpected limitations or bugs, | ||
please <a href="https://github.com/Kotlin/kotlinx-rpc/issues/new?template=bug_report.md">report</a> them | ||
</p> | ||
</chapter> | ||
</topic> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use the version defined in the
v.list
file like this:%kotlinx-rpc-version%
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't define a dynamic version there. For gRPC it may be updated a lot of times, and I don't want to change the docs every time. Badge renders latest version dynamically.