Skip to content

Commit b31d6e4

Browse files
committed
Add kxrpc grpc plugin
1 parent b90ed4e commit b31d6e4

File tree

9 files changed

+199
-0
lines changed

9 files changed

+199
-0
lines changed

plugins/gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ exposed=0.+
33
h2=2.3.+
44
koin=3.5.+
55
kotlinx-rpc=0.9.1
6+
kotlinx-rpc-grpc=0.10.0-grpc-121
67
kotlinx-html=0.+
78
mongo=4.10.+
89
postgres=42.7.+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class SampleServiceImpl : SampleService {
2+
override suspend fun greeting(name: ClientGreeting): ServerGreeting {
3+
return ServerGreeting { content = "Hello, ${name.name}!" }
4+
}
5+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
Add gRPC services to your Ktor application!
2+
3+
# Usage
4+
5+
## DISCLAIMER
6+
**This is a dev preview of the kotlinx-rpc gRPC plugin for Ktor. It is not yet ready for production use.
7+
The artifacts provided are dev artifacts, and the API may and will change in the future.**
8+
9+
**Please use it to play with the plugin. We will appreciate any feedback on the
10+
[Github](https://github.com/Kotlin/kotlinx-rpc/issues)
11+
or in [Slack](https://kotlinlang.slack.com/archives/C072YJ3Q91V)**
12+
13+
## gRPC Server
14+
You can add gRPC services to your Ktor application by using the `grpc` function provided by the plugin.
15+
Here's an example:
16+
17+
Declare a service in a `.proto` file.
18+
```protobuf
19+
syntax = "proto3";
20+
21+
message ClientGreeting {
22+
string name = 1;
23+
}
24+
25+
message ServerGreeting {
26+
string content = 2;
27+
}
28+
29+
service SampleService {
30+
rpc greeting(ClientGreeting) returns (ServerGreeting);
31+
}
32+
```
33+
34+
The `SampleService` interface will generated for you alongside with other types and helper declarations.
35+
36+
Define an implementation. Then register it on the server and all done:
37+
38+
```kotlin
39+
class SampleServiceImpl : SampleService {
40+
override suspend fun greeting(name: ClientGreeting): ServerGreeting {
41+
return ServerGreeting { content = "Hello, ${name.name}!" }
42+
}
43+
}
44+
45+
fun Application.module() {
46+
grpc {
47+
registerService<SampleService> { SampleServiceImpl() }
48+
}
49+
}
50+
```
51+
52+
## gRPC Client
53+
You can use any gRPC client on the other end, but also you can use ours!
54+
55+
To do that - use the `GrpcClient` class:
56+
```Kotlin
57+
val client = GrpcClient("localhost", 8081) {
58+
usePlaintext()
59+
}
60+
61+
val response = client.withService<SampleService>().greeting(
62+
ClientGreeting {
63+
name = "Alex"
64+
}
65+
)
66+
67+
assertEquals("Hello, Alex!", response.content, "Wrong response message")
68+
69+
client.close()
70+
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import io.ktor.server.application.Application
2+
import kotlinx.rpc.grpc.ktor.server.grpc
3+
import kotlinx.rpc.registerService
4+
5+
fun Application.install() {
6+
grpc {
7+
registerService<SampleService> { SampleServiceImpl() }
8+
}
9+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: gRPC
2+
description: Add gRPC services to your Ktor server with kotlinx.rpc
3+
vcsLink: https://github.com/Kotlin/kotlinx-rpc
4+
license: Apache 2.0
5+
category: Frameworks
6+
maven:
7+
disabled: true
8+
# TODO KRPC-131 waiting for fixes to enable amper support
9+
amper:
10+
disabled: true
11+
gradle:
12+
pluginRepositories:
13+
- url: https://maven.pkg.jetbrains.space/public/p/krpc/grpc
14+
repositories:
15+
- url: https://maven.pkg.jetbrains.space/public/p/krpc/grpc
16+
plugins:
17+
- id: org.jetbrains.kotlinx.rpc.plugin
18+
version: $kotlinx-rpc-grpc
19+
installation:
20+
inside_app: inside_app.kt
21+
test_function: test.kt
22+
gradle_build: |-
23+
rpc {
24+
grpc()
25+
}
26+
sources:
27+
- SampleServiceImpl.kt
28+
29+
# I need src/main/proto structure
30+
#
31+
#mainSourceSet:
32+
# - proto/service.proto
33+
34+
# Or Maybe?
35+
#src:
36+
# - main:
37+
# - proto:
38+
# - proto/service.proto
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
syntax = "proto3";
2+
3+
package io.ktor;
4+
5+
message ClientGreeting {
6+
string name = 1;
7+
}
8+
9+
message ServerGreeting {
10+
string content = 2;
11+
}
12+
13+
service SampleService {
14+
rpc greeting(ClientGreeting) returns (ServerGreeting);
15+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// DO NOT DELETE, not included in generation, but is used for code highlighting in registry
2+
3+
class ClientGreeting {
4+
var name: String = ""
5+
6+
companion object {
7+
operator fun invoke(body: ClientGreeting.() -> Unit): ClientGreeting = ClientGreeting().apply(body)
8+
}
9+
}
10+
11+
class ServerGreeting {
12+
var content: String = ""
13+
14+
companion object {
15+
operator fun invoke(body: ServerGreeting.() -> Unit): ServerGreeting = ServerGreeting().apply(body)
16+
}
17+
}
18+
19+
interface SampleService {
20+
suspend fun greeting(name: ClientGreeting): ServerGreeting
21+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import io.ktor.server.testing.testApplication
2+
import kotlinx.rpc.grpc.GrpcClient
3+
import kotlinx.rpc.grpc.ktor.server.grpc
4+
import kotlinx.rpc.registerService
5+
import kotlinx.rpc.withService
6+
import kotlin.test.Test
7+
import kotlin.test.assertEquals
8+
import kotlin.time.Duration.Companion.minutes
9+
10+
class ApplicationRpcTest {
11+
@Test
12+
fun testRpc() = testApplication {
13+
application {
14+
grpc(8081) {
15+
registerService<SampleService> { SampleServiceImpl() }
16+
}
17+
}
18+
19+
startApplication()
20+
21+
val client = GrpcClient("localhost", 8081) {
22+
usePlaintext()
23+
}
24+
25+
val response = client.withService<SampleService>().greeting(
26+
ClientGreeting {
27+
name = "Alex"
28+
}
29+
)
30+
31+
assertEquals("Hello, Alex!", response.content, "Wrong response message")
32+
33+
client.shutdown()
34+
client.awaitTermination(1.minutes)
35+
}
36+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"[3.0,)":
2+
- org.jetbrains.kotlinx:kotlinx-rpc-grpc-ktor-server:$kotlinx-rpc-grpc
3+
- io.grpc:grpc-netty:1.73.0
4+
- io.grpc:grpc-kotlin-stub:1.4.1

0 commit comments

Comments
 (0)