Skip to content

Commit 0816e21

Browse files
authored
feat: serialization and versioning support (#9)
* feat: `serialization` & `versioning` support is added * docs: documentation improvements (for the new artifacts, root one)
1 parent 8a5c724 commit 0816e21

File tree

49 files changed

+1572
-343
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1572
-343
lines changed

.github/workflows/publish-release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
- name: Set up Java
1717
uses: actions/setup-java@v3
1818
with:
19-
java-version: '17'
19+
java-version: '11'
2020
distribution: 'corretto'
2121

2222
- name: Cache Gradle dependencies
@@ -35,4 +35,4 @@ jobs:
3535
SSH_HOST: ${{ secrets.SSH_HOST }}
3636
SSH_PASSWORD: ${{ secrets.SSH_PASSWORD }}
3737
SSH_USER: ${{ secrets.SSH_USER }}
38-
run: ./gradlew publish -Pversion=dev-${{ env.LIB_VERSION }}
38+
run: ./gradlew publish

README.md

Lines changed: 112 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,63 @@
1-
![GitHub release (with filter)](https://img.shields.io/github/v/release/y9vad9/rsocket-kotlin-router)
2-
![GitHub](https://img.shields.io/github/license/y9vad9/rsocket-kotlin-router)
3-
# rsocket-kotlin-router
4-
`rsocket-kotlin-router` is a customizable library designed to streamline and simplify routing
1+
![GitHub release](https://img.shields.io/github/v/release/y9vad9/rsocket-kotlin-router) ![GitHub](https://img.shields.io/github/license/y9vad9/rsocket-kotlin-router)
2+
# RSocket Router
3+
4+
`rsocket-kotlin-router` is a customisable library designed to streamline and simplify routing
55
for RSocket Kotlin server applications. This library offers a typesafe DSL for handling various
66
routes, serving as a declarative simplified alternative to manual routing that would
7-
otherwise, result in long-winded ternary logic or exhaustive when statements.
7+
otherwise result in long-winded ternary logic or exhaustive when statements.
8+
9+
Library provides the following features:
10+
- [Routing Builder](#Interceptors)
11+
- [Interceptors](#Interceptors)
12+
- [Request Versioning](router-versioning)
13+
- [Request Serialization](router-serialization)
814

9-
## Features
10-
### Router
11-
It's the basic thing in the `rsocket-kotlin-router` that's responsible for managing routes, their settings, etc. You
12-
can define it in the following way:
15+
## How to use
16+
First of all, you need to implement basic artifacts with routing support. For now, `rsocket-kotlin-router`
17+
is available only at my self-hosted maven:
1318
```kotlin
14-
val ServerRouter = router {
15-
router {
16-
routeSeparator = '.'
17-
routeProvider { metadata ->
18-
metadata?.read(RoutingMetadata)?.tags?.first()
19-
?: throw RSocketError.Invalid("No routing metadata was provided")
20-
}
21-
22-
routing { // this: RoutingBuilder
23-
// ...
24-
}
25-
}
19+
repositories {
20+
maven("https://maven.y9vad9.com")
2621
}
27-
```
28-
To install it later, you can use `Router.installOn(RSocketRequestHandlerBuilder)` function:
29-
```kotlin
30-
fun ServerRequestHandler(router: Router): RSocket = RSocketRequestHandlerBuilder {
31-
router.installOn(this)
22+
23+
dependencies {
24+
implementation("com.y9vad9.rsocket.router:router-core:$version")
3225
}
3326
```
34-
Or you can call `router` function directly in the `RSocketRequestHandlerBuilder` context – it will automatically
35-
install router on the given context.
27+
> For now, it's available for JVM only, but as there is no JVM platform API used,
28+
> new targets will be available [upon your request](https://github.com/y9vad9/rsocket-kotlin-router/issues/new).
3629
37-
### Routing Builder
38-
You can define routes using bundled DSL-Builder functions:
30+
Example of defining RSocket router:
3931
```kotlin
40-
fun RoutingBuilder.usersRoute(): Unit = route("users") {
41-
// extension function that wraps RSocket `requestResponse` into `route` with given path.
42-
requestResponse("get") { payload -> TODO() }
43-
44-
// ... other
32+
val serverRouter = router {
33+
routeSeparator = '.'
34+
routeProvider { metadata: ByteReadPacket? ->
35+
metadata?.read(RoutingMetadata)?.tags?.first()
36+
?: throw RSocketError.Invalid("No routing metadata was provided")
37+
}
38+
39+
routing { // this: RoutingBuilder
40+
route("authorization") {
41+
requestResponse("register") { payload: Payload ->
42+
// just 4 example
43+
println(payload.data.readText())
44+
Payload.Empty
45+
}
46+
}
47+
}
4548
}
4649
```
47-
> **Note** <br>
48-
> The library does not include the functionality to add routing to a `metadataPush` type of request. I am not sure
49-
> how it should be exactly implemented (API), so your ideas are welcome. For now, I consider it a per-project responsibility.
50-
### Interceptors
51-
> **Warning** <br>
52-
> Interceptors are experimental feature: API can be changed in the future.
53-
54-
#### Preprocessors
55-
Preprocessors are utilities that run before the routing feature applies. For cases, when you need to transform input into something or propagate
56-
values using coroutines – you can extend [`Preprocessor.Modifier`](https://github.com/y9vad9/rsocket-kotlin-router/blob/8bace098e0a47e3cf514eec0dfb702f7e4e13591/router-core/src/commonMain/kotlin/com.y9vad9.rsocket.router/interceptors/Interceptor.kt#L35) or [`Preprocessor.CoroutineContext`](https://github.com/y9vad9/rsocket-kotlin-router/blob/8bace098e0a47e3cf514eec0dfb702f7e4e13591/router-core/src/commonMain/kotlin/com.y9vad9.rsocket.router/interceptors/Interceptor.kt#L27). Here's an example:
50+
51+
See also what else is supported:
52+
53+
<details id="Interceptors">
54+
<summary>Interceptors</summary>
55+
<i>Interceptors are experimental feature: API can be changed in the future.</i>
56+
57+
<b id="Preprocessors">Preprocessors</b>
58+
59+
Preprocessors are utilities that run before routing feature applies. For cases, when you need to transform input into something or propagate
60+
values using coroutines – you can extend [`Preprocessor.Modifier`](https://github.com/y9vad9/rsocket-kotlin-router/blob/2a794e9a8c5d2ac53cb87ea58cfbe4a2ecfa217d/router-core/src/commonMain/kotlin/com.y9vad9.rsocket.router/interceptors/Interceptor.kt#L39) or [`Preprocessor.CoroutineContext`](https://github.com/y9vad9/rsocket-kotlin-router/blob/master/router-core/src/commonMain/kotlin/com.y9vad9.rsocket.router/interceptors/Interceptor.kt#L31). Here's an example:
5761
```kotlin
5862
class MyCoroutineContextElement(val value: String): CoroutineContext.Element {...}
5963

@@ -65,7 +69,8 @@ class MyCoroutineContextPreprocessor : Preprocessor.CoroutineContext {
6569
}
6670
```
6771

68-
#### Route Interceptors
72+
<b id="RouteInterceptors">Route Interceptors</b>
73+
6974
In addition to the `Preprocessors`, `rsocket-kotlin-router` also provides API to intercept specific routes:
7075
```kotlin
7176
@OptIn(ExperimentalInterceptorsApi::class)
@@ -75,9 +80,61 @@ class MyRouteInterceptor : RouteInterceptor.Modifier {
7580
}
7681
}
7782
```
78-
It has the same abilities as Preprocessors. You can take a look at it [here](https://github.com/y9vad9/rsocket-kotlin-router/blob/8bace098e0a47e3cf514eec0dfb702f7e4e13591/router-core/src/commonMain/kotlin/com.y9vad9.rsocket.router/interceptors/Interceptor.kt#L45).
79-
### Testability
83+
84+
<b>Installation</b>
85+
```kotlin
86+
val serverRouter = router {
87+
preprocessors {
88+
forCoroutineContext(MyCoroutineContextPreprocessor())
89+
}
90+
91+
sharedInterceptors {
92+
forModification(MyRouteInterceptor())
93+
}
94+
}
95+
```
96+
</details>
97+
98+
<details>
99+
<summary>Versioning support</summary>
100+
101+
To use request versioning in your project, use the following artifact:
102+
103+
```kotlin
104+
dependencies {
105+
// ...
106+
implementation("com.y9vad9.rsocket.router:router-versioning-core:$version")
107+
}
108+
```
109+
For details, please refer to the [versioning guide](router-versioning/README.md).
110+
</details>
111+
112+
<details>
113+
<summary>Serialization support</summary>
114+
115+
To make type-safe requests with serialization/deserialization mechanisms, implement the following:
116+
117+
```kotlin
118+
dependencies {
119+
implementation("com.y9vad9.rsocket.router:router-serialization-core:$version")
120+
// for JSON support
121+
implementation("com.y9vad9.rsocket.router:router-serialization-json:$version")
122+
}
123+
```
124+
For details, please refer to the [serialization guide](router-serialization/README.md).
125+
</details>
126+
127+
<details>
128+
<summary>Testing</summary>
129+
80130
`rsocket-kotlin-router` provides ability to test your routes with `router-test` artifact:
131+
132+
```kotlin
133+
dependencies {
134+
implementation("com.y9vad9.rsocket.router:router-test:$version")
135+
}
136+
```
137+
81138
```kotlin
82139
@Test
83140
fun testRoutes() {
@@ -94,20 +151,12 @@ fun testRoutes() {
94151
}
95152
}
96153
```
97-
You can refer to [full example](router-test/src/jvmTest/kotlin/com/y9vad9/rsocket/router/test/RouterTest.kt).
98154

99-
## Implementation
100-
To implement this library, you should define the following:
101-
```kotlin
102-
repositories {
103-
maven("https://maven.y9vad9.com")
104-
}
155+
You can refer to the [example](router-core/test/src/jvmTest/kotlin/com/y9vad9/rsocket/router/test/RouterTest.kt) for more details.
156+
</details>
105157

106-
dependencies {
107-
implementation("com.y9vad9.rsocket.router:router-core:$version")
108-
// for testing
109-
implementation("com.y9vad9.rsocket.router:router-test:$version")
110-
}
111-
```
112-
> For now, it's available for JVM only, but as there is no JVM platform API used,
113-
> new targets will be available [upon your request](https://github.com/y9vad9/rsocket-kotlin-router/issues/new).
158+
## Bugs and Feedback
159+
For bugs, questions and discussions please use the [GitHub Issues](https://github.com/y9vad9/rsocket-kotlin-router/issues).
160+
161+
## License
162+
This library is licensed under [MIT License](LICENSE). Feel free to use, modify, and distribute it for any purpose.

build-conventions/build.gradle.kts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
plugins {
2+
`kotlin-dsl`
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
google()
8+
gradlePluginPortal()
9+
}
10+
11+
kotlin {
12+
jvmToolchain(11)
13+
}
14+
15+
dependencies {
16+
api(libs.kotlin.plugin)
17+
api(libs.vanniktech.maven.publish)
18+
}

build-conventions/settings.gradle.kts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
dependencyResolutionManagement {
2+
repositories {
3+
mavenCentral()
4+
google()
5+
}
6+
7+
versionCatalogs {
8+
create("libs") {
9+
from(files("../gradle/libs.versions.toml"))
10+
}
11+
}
12+
}
13+
14+
rootProject.name = "conventions"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import org.jetbrains.kotlin.gradle.dsl.*
2+
3+
plugins {
4+
kotlin("multiplatform")
5+
id("com.vanniktech.maven.publish")
6+
}
7+
8+
kotlin {
9+
jvm()
10+
jvmToolchain(11)
11+
12+
explicitApi = ExplicitApiMode.Strict
13+
}
14+
15+
mavenPublishing {
16+
pom {
17+
url.set("https://github.com/y9vad9/rsocket-kotlin-router")
18+
inceptionYear.set("2023")
19+
20+
licenses {
21+
license {
22+
name.set("The MIT License")
23+
url.set("https://opensource.org/licenses/MIT")
24+
distribution.set("https://opensource.org/licenses/MIT")
25+
}
26+
}
27+
28+
developers {
29+
developer {
30+
id.set("y9vad9")
31+
name.set("Vadym Yaroshchuk")
32+
url.set("https://github.com/y9vad9/")
33+
}
34+
}
35+
36+
scm {
37+
url.set("https://github.com/y9vad9/rsocket-kotlin-router")
38+
connection.set("scm:git:git://github.com/y9vad9/rsocket-kotlin-router.git")
39+
developerConnection.set("scm:git:ssh://git@github.com/y9vad9/rsocket-kotlin-router.git")
40+
}
41+
42+
issueManagement {
43+
system.set("GitHub Issues")
44+
url.set("https://github.com/y9vad9/rsocket-kotlin-router/issues")
45+
}
46+
}
47+
}
48+
49+
publishing {
50+
repositories {
51+
maven {
52+
name = "y9vad9Maven"
53+
54+
url = uri(
55+
"sftp://${System.getenv("SSH_HOST")}:22/${System.getenv("SSH_DEPLOY_PATH")}"
56+
)
57+
58+
credentials {
59+
username = System.getenv("SSH_USER")
60+
password = System.getenv("SSH_PASSWORD")
61+
}
62+
}
63+
}
64+
}

build-logic/publish-library-plugin/build.gradle.kts

Lines changed: 0 additions & 23 deletions
This file was deleted.

build-logic/publish-library-plugin/settings.gradle.kts

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)