Skip to content

Commit ef6d383

Browse files
authored
Feature/update kotlin dependecies template (#12966)
* update Kotlin & Ktor versions * update samples * fix gradle version * update the ktor client templates and project samples * update the ktor client templates and project samples * revert multiplatform upgrade * update kotlin multiplatform * upload kotlin Multiplatform samples * fix gson ktor sample * update samples * fix: unused imports * fix imports of ApiClient * update kotlin samples
1 parent f6be1d0 commit ef6d383

File tree

68 files changed

+466
-587
lines changed

Some content is hidden

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

68 files changed

+466
-587
lines changed

modules/openapi-generator/src/main/resources/kotlin-client/build.gradle.mustache

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ version '{{artifactVersion}}'
33
{{^omitGradleWrapper}}
44

55
wrapper {
6-
gradleVersion = '6.8.3'
6+
gradleVersion = '7.5'
77
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip"
88
}
99
{{/omitGradleWrapper}}
1010

1111
buildscript {
12-
ext.kotlin_version = '1.5.10'
12+
ext.kotlin_version = '1.6.10'
1313
{{#jvm-ktor}}
14-
ext.ktor_version = '1.6.7'
14+
ext.ktor_version = '2.0.3'
1515
{{/jvm-ktor}}
1616
{{#jvm-retrofit2}}
1717
ext.retrofitVersion = '2.9.0'
@@ -72,46 +72,49 @@ dependencies {
7272
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
7373
{{^doNotUseRxAndCoroutines}}
7474
{{#useCoroutines}}
75-
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1"
75+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3"
7676
{{/useCoroutines}}
7777
{{/doNotUseRxAndCoroutines}}
7878
{{#moshi}}
7979
{{^moshiCodeGen}}
8080
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
81-
implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
82-
implementation "com.squareup.moshi:moshi-adapters:1.12.0"
81+
implementation "com.squareup.moshi:moshi-kotlin:1.13.0"
82+
implementation "com.squareup.moshi:moshi-adapters:1.13.0"
8383
{{/moshiCodeGen}}
8484
{{#moshiCodeGen}}
85-
implementation "com.squareup.moshi:moshi:1.12.0"
86-
implementation "com.squareup.moshi:moshi-adapters:1.12.0"
87-
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.12.0"
85+
implementation "com.squareup.moshi:moshi:1.13.0"
86+
implementation "com.squareup.moshi:moshi-adapters:1.13.0"
87+
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.13.0"
8888
{{/moshiCodeGen}}
8989
{{/moshi}}
9090
{{#gson}}
91-
implementation "com.google.code.gson:gson:2.8.7"
91+
implementation "com.google.code.gson:gson:2.9.0"
9292
{{/gson}}
9393
{{#jackson}}
9494
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
95-
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.3"
96-
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3"
95+
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3"
96+
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.3"
9797
{{/jackson}}
9898
{{#kotlinx_serialization}}
99-
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1"
99+
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3"
100100
{{/kotlinx_serialization}}
101101
{{#jvm-ktor}}
102102
implementation "io.ktor:ktor-client-core:$ktor_version"
103+
implementation "io.ktor:ktor-client-content-negotiation:$ktor_version"
103104
{{#gson}}
105+
implementation "io.ktor:ktor-serialization-gson:$ktor_version"
104106
implementation "io.ktor:ktor-client-gson:$ktor_version"
105107
{{/gson}}
106108
{{#jackson}}
107109
implementation "io.ktor:ktor-client-jackson:$ktor_version"
110+
implementation "io.ktor:ktor-serialization-jackson:$ktor_version"
108111
{{/jackson}}
109112
{{/jvm-ktor}}
110113
{{#jvm-okhttp3}}
111114
implementation "com.squareup.okhttp3:okhttp:3.12.13"
112115
{{/jvm-okhttp3}}
113116
{{#jvm-okhttp4}}
114-
implementation "com.squareup.okhttp3:okhttp:4.9.1"
117+
implementation "com.squareup.okhttp3:okhttp:4.10.0"
115118
{{/jvm-okhttp4}}
116119
{{#threetenbp}}
117120
implementation "org.threeten:threetenbp:1.5.1"
@@ -120,7 +123,7 @@ dependencies {
120123
{{#hasOAuthMethods}}
121124
implementation "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:1.0.2"
122125
{{/hasOAuthMethods}}
123-
implementation "com.squareup.okhttp3:logging-interceptor:4.9.1"
126+
implementation "com.squareup.okhttp3:logging-interceptor:4.10.0"
124127
{{#useRxJava}}
125128
implementation "io.reactivex:rxjava:$rxJavaVersion"
126129
implementation "com.squareup.retrofit2:adapter-rxjava:$retrofitVersion"

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/api.mustache

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import io.ktor.client.HttpClientConfig
99
import io.ktor.client.request.forms.formData
1010
import io.ktor.client.engine.HttpClientEngine
1111
import io.ktor.http.ParametersBuilder
12-
1312
{{#gson}}
1413
import com.google.gson.Gson
14+
import com.google.gson.GsonBuilder
15+
import java.text.DateFormat
1516
{{/gson}}
1617
{{#jackson}}
1718
import com.fasterxml.jackson.databind.ObjectMapper
@@ -22,8 +23,13 @@ import com.fasterxml.jackson.databind.ObjectMapper
2223
baseUrl: String = ApiClient.BASE_URL,
2324
httpClientEngine: HttpClientEngine? = null,
2425
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
25-
json: {{#gson}}Gson{{/gson}}{{#jackson}}ObjectMapper{{/jackson}} = ApiClient.JSON_DEFAULT,
26-
) : ApiClient(baseUrl, httpClientEngine, httpClientConfig, json) {
26+
{{#gson}}
27+
jsonBlock: GsonBuilder.() -> Unit = ApiClient.JSON_DEFAULT,
28+
{{/gson}}
29+
{{#jackson}}
30+
jsonBlock: ObjectMapper.() -> Unit = ApiClient.JSON_DEFAULT,
31+
{{/jackson}}
32+
) : ApiClient(baseUrl, httpClientEngine, httpClientConfig, jsonBlock) {
2733
2834
{{#operation}}
2935
/**

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/infrastructure/ApiClient.kt.mustache

Lines changed: 67 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,68 @@
11
package {{packageName}}.infrastructure
22

3+
34
import io.ktor.client.HttpClient
45
import io.ktor.client.HttpClientConfig
56
import io.ktor.client.engine.HttpClientEngine
6-
import io.ktor.client.features.json.JsonFeature
7-
import io.ktor.client.features.json.JsonSerializer
8-
import io.ktor.client.request.*
7+
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
98
import io.ktor.client.request.forms.FormDataContent
109
import io.ktor.client.request.forms.MultiPartFormDataContent
1110
import io.ktor.client.request.header
1211
import io.ktor.client.request.parameter
12+
import io.ktor.client.request.request
13+
import io.ktor.client.request.setBody
1314
import io.ktor.client.statement.HttpResponse
14-
import io.ktor.client.utils.EmptyContent
15-
import io.ktor.http.*
16-
import io.ktor.http.content.ByteArrayContent
17-
import io.ktor.http.content.OutgoingContent
15+
import io.ktor.http.HttpHeaders
16+
import io.ktor.http.HttpMethod
17+
import io.ktor.http.Parameters
18+
import io.ktor.http.URLBuilder
1819
import io.ktor.http.content.PartData
19-
import kotlin.Unit
20-
20+
import io.ktor.http.encodeURLQueryComponent
21+
import io.ktor.http.encodedPath
22+
import io.ktor.http.takeFrom
2123
{{#gson}}
22-
import com.google.gson.Gson
23-
import java.nio.charset.StandardCharsets
24+
import io.ktor.serialization.gson.*
25+
import com.google.gson.GsonBuilder
26+
import java.text.DateFormat
2427
{{/gson}}
2528
{{#jackson}}
29+
import io.ktor.serialization.jackson.*
30+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
2631
import com.fasterxml.jackson.databind.ObjectMapper
32+
import com.fasterxml.jackson.databind.SerializationFeature
33+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
34+
import com.fasterxml.jackson.core.util.DefaultIndenter
35+
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter
2736
{{/jackson}}
28-
37+
import org.openapitools.client.auth.ApiKeyAuth
38+
import org.openapitools.client.auth.Authentication
39+
import org.openapitools.client.auth.HttpBasicAuth
40+
import org.openapitools.client.auth.HttpBearerAuth
41+
import org.openapitools.client.auth.OAuth
2942
import {{packageName}}.auth.*
3043

3144
{{#nonPublicApi}}internal {{/nonPublicApi}}open class ApiClient(
3245
private val baseUrl: String,
3346
httpClientEngine: HttpClientEngine?,
3447
httpClientConfig: ((HttpClientConfig<*>) -> Unit)? = null,
35-
json: {{#gson}}Gson{{/gson}}{{#jackson}}ObjectMapper{{/jackson}},
48+
{{#gson}}
49+
jsonBlock: GsonBuilder.() -> Unit = JSON_DEFAULT,
50+
{{/gson}}
51+
{{#jackson}}
52+
jsonBlock: ObjectMapper.() -> Unit = JSON_DEFAULT,
53+
{{/jackson}}
3654
) {
3755
38-
private val serializer: JsonSerializer by lazy {
39-
JsonSerializerImpl(json)
40-
}
41-
4256
private val clientConfig: (HttpClientConfig<*>) -> Unit by lazy {
4357
{
44-
// Hold a reference to the serializer to avoid freezing the entire ApiClient instance
45-
// when the JsonFeature is configured.
46-
val serializerReference = serializer
47-
it.install(JsonFeature) { serializer = serializerReference }
58+
it.install(ContentNegotiation) {
59+
{{#gson}}
60+
gson { jsonBlock() }
61+
{{/gson}}
62+
{{#jackson}}
63+
jackson { jsonBlock() }
64+
{{/jackson}}
65+
}
4866
httpClientConfig?.invoke(it)
4967
}
5068
}
@@ -67,9 +85,24 @@ import {{packageName}}.auth.*
6785
{{/hasAuthMethods}}
6886

6987
{{#nonPublicApi}}internal {{/nonPublicApi}}companion object {
70-
const val BASE_URL = "{{{basePath}}}"
71-
val JSON_DEFAULT = {{#gson}}Gson(){{/gson}}{{#jackson}}ObjectMapper(){{/jackson}}
72-
protected val UNSAFE_HEADERS = listOf(HttpHeaders.ContentType)
88+
const val BASE_URL = "{{{basePath}}}"
89+
{{#gson}}
90+
val JSON_DEFAULT : GsonBuilder.() -> Unit = {
91+
setDateFormat(DateFormat.LONG)
92+
setPrettyPrinting()
93+
}
94+
{{/gson}}
95+
{{#jackson}}
96+
val JSON_DEFAULT: ObjectMapper.() -> Unit = {
97+
configure(SerializationFeature.INDENT_OUTPUT, true)
98+
setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
99+
indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
100+
indentObjectsWith(DefaultIndenter(" ", "\n"))
101+
})
102+
registerModule(JavaTimeModule())
103+
}
104+
{{/jackson}}
105+
protected val UNSAFE_HEADERS = listOf(HttpHeaders.ContentType)
73106
}
74107

75108
/**
@@ -78,7 +111,7 @@ import {{packageName}}.auth.*
78111
* @param username Username
79112
*/
80113
fun setUsername(username: String) {
81-
val auth = authentications?.values?.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
114+
val auth = authentications.values.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
82115
?: throw Exception("No HTTP basic authentication configured")
83116
auth.username = username
84117
}
@@ -89,7 +122,7 @@ import {{packageName}}.auth.*
89122
* @param password Password
90123
*/
91124
fun setPassword(password: String) {
92-
val auth = authentications?.values?.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
125+
val auth = authentications.values.firstOrNull { it is HttpBasicAuth } as HttpBasicAuth?
93126
?: throw Exception("No HTTP basic authentication configured")
94127
auth.password = password
95128
}
@@ -101,7 +134,7 @@ import {{packageName}}.auth.*
101134
* @param paramName The name of the API key parameter, or null or set the first key.
102135
*/
103136
fun setApiKey(apiKey: String, paramName: String? = null) {
104-
val auth = authentications?.values?.firstOrNull { it is ApiKeyAuth && (paramName == null || paramName == it.paramName)} as ApiKeyAuth?
137+
val auth = authentications.values.firstOrNull { it is ApiKeyAuth && (paramName == null || paramName == it.paramName)} as ApiKeyAuth?
105138
?: throw Exception("No API key authentication configured")
106139
auth.apiKey = apiKey
107140
}
@@ -113,7 +146,7 @@ import {{packageName}}.auth.*
113146
* @param paramName The name of the API key parameter, or null or set the first key.
114147
*/
115148
fun setApiKeyPrefix(apiKeyPrefix: String, paramName: String? = null) {
116-
val auth = authentications?.values?.firstOrNull { it is ApiKeyAuth && (paramName == null || paramName == it.paramName) } as ApiKeyAuth?
149+
val auth = authentications.values.firstOrNull { it is ApiKeyAuth && (paramName == null || paramName == it.paramName) } as ApiKeyAuth?
117150
?: throw Exception("No API key authentication configured")
118151
auth.apiKeyPrefix = apiKeyPrefix
119152
}
@@ -124,7 +157,7 @@ import {{packageName}}.auth.*
124157
* @param accessToken Access token
125158
*/
126159
fun setAccessToken(accessToken: String) {
127-
val auth = authentications?.values?.firstOrNull { it is OAuth } as OAuth?
160+
val auth = authentications.values.firstOrNull { it is OAuth } as OAuth?
128161
?: throw Exception("No OAuth2 authentication configured")
129162
auth.accessToken = accessToken
130163
}
@@ -135,7 +168,7 @@ import {{packageName}}.auth.*
135168
* @param bearerToken The bearer token.
136169
*/
137170
fun setBearerToken(bearerToken: String) {
138-
val auth = authentications?.values?.firstOrNull { it is HttpBearerAuth } as HttpBearerAuth?
171+
val auth = authentications.values.firstOrNull { it is HttpBearerAuth } as HttpBearerAuth?
139172
?: throw Exception("No Bearer authentication configured")
140173
auth.bearerToken = bearerToken
141174
}
@@ -148,18 +181,13 @@ import {{packageName}}.auth.*
148181
return request(requestConfig, FormDataContent(body ?: Parameters.Empty), authNames)
149182
}
150183

151-
protected suspend fun <T: Any?> jsonRequest(requestConfig: RequestConfig<T>, body: Any? = null, authNames: kotlin.collections.List<String>): HttpResponse {
152-
val contentType = (requestConfig.headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) }
153-
?: ContentType.Application.Json)
154-
return if (body != null) request(requestConfig, serializer.write(body, contentType), authNames)
155-
else request(requestConfig, authNames = authNames)
156-
}
184+
protected suspend fun <T: Any?> jsonRequest(requestConfig: RequestConfig<T>, body: Any? = null, authNames: kotlin.collections.List<String>): HttpResponse = request(requestConfig, body, authNames)
157185

158-
protected suspend fun <T: Any?> request(requestConfig: RequestConfig<T>, body: OutgoingContent = EmptyContent, authNames: kotlin.collections.List<String>): HttpResponse {
186+
protected suspend fun <T: Any?> request(requestConfig: RequestConfig<T>, body: Any? = null, authNames: kotlin.collections.List<String>): HttpResponse {
159187
requestConfig.updateForAuth<T>(authNames)
160188
val headers = requestConfig.headers
161189
162-
return client.request<HttpResponse> {
190+
return client.request {
163191
this.url {
164192
this.takeFrom(URLBuilder(baseUrl))
165193
appendPath(requestConfig.path.trimStart('/').split('/'))
@@ -172,8 +200,7 @@ import {{packageName}}.auth.*
172200
this.method = requestConfig.method.httpMethod
173201
headers.filter { header -> !UNSAFE_HEADERS.contains(header.key) }.forEach { header -> this.header(header.key, header.value) }
174202
if (requestConfig.method in listOf(RequestMethod.PUT, RequestMethod.POST, RequestMethod.PATCH))
175-
this.body = body
176-
203+
setBody(body)
177204
}
178205
}
179206

@@ -199,13 +226,3 @@ import {{packageName}}.auth.*
199226
RequestMethod.OPTIONS -> HttpMethod.Options
200227
}
201228
}
202-
203-
{{#gson}}private class JsonSerializerImpl(private val gson: Gson) : JsonSerializer {
204-
override fun write(data: Any, contentType: ContentType): OutgoingContent =
205-
ByteArrayContent(gson.toJson(data).toByteArray(StandardCharsets.UTF_8), contentType)
206-
}{{/gson}}
207-
208-
{{#jackson}}private class JsonSerializerImpl(private val objectMapper: ObjectMapper) : JsonSerializer {
209-
override fun write(data: Any, contentType: ContentType): OutgoingContent =
210-
ByteArrayContent(objectMapper.writeValueAsBytes(data), contentType)
211-
}{{/jackson}}

modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-ktor/infrastructure/HttpResponse.kt.mustache

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package {{packageName}}.infrastructure
22

3-
import io.ktor.client.call.TypeInfo
4-
import io.ktor.client.call.typeInfo
53
import io.ktor.http.Headers
64
import io.ktor.http.isSuccess
5+
import io.ktor.util.reflect.TypeInfo
6+
import io.ktor.util.reflect.typeInfo
77

88
{{#nonPublicApi}}internal {{/nonPublicApi}}open class HttpResponse<T : Any>(val response: io.ktor.client.statement.HttpResponse, val provider: BodyProvider<T>) {
99
val status: Int = response.status.value
@@ -29,11 +29,11 @@ import io.ktor.http.isSuccess
2929
{{#nonPublicApi}}internal {{/nonPublicApi}}class TypedBodyProvider<T : Any>(private val type: TypeInfo) : BodyProvider<T> {
3030
@Suppress("UNCHECKED_CAST")
3131
override suspend fun body(response: io.ktor.client.statement.HttpResponse): T =
32-
response.call.receive(type) as T
32+
response.call.body(type) as T
3333
3434
@Suppress("UNCHECKED_CAST")
3535
override suspend fun <V : Any> typedBody(response: io.ktor.client.statement.HttpResponse, type: TypeInfo): V =
36-
response.call.receive(type) as V
36+
response.call.body(type) as V
3737
}
3838

3939
{{#nonPublicApi}}internal {{/nonPublicApi}}class MappedBodyProvider<S : Any, T : Any>(private val provider: BodyProvider<S>, private val block: S.() -> T) : BodyProvider<T> {

modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/api.mustache

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {{packageName}}.infrastructure.*
88
import io.ktor.client.HttpClientConfig
99
import io.ktor.client.request.forms.formData
1010
import io.ktor.client.engine.HttpClientEngine
11-
import io.ktor.client.features.json.serializer.KotlinxSerializer
1211
import kotlinx.serialization.json.Json
1312
import io.ktor.http.ParametersBuilder
1413
import kotlinx.serialization.*

modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/build.gradle.kts.mustache

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ plugins {
88
group = "{{groupId}}"
99
version = "{{artifactVersion}}"
1010

11-
val kotlin_version = "1.6.0"
12-
val coroutines_version = "1.5.2"
13-
val serialization_version = "1.3.0"
14-
val ktor_version = "1.6.4"
11+
val kotlin_version = "1.6.10"
12+
val coroutines_version = "1.6.3"
13+
val serialization_version = "1.3.3"
14+
val ktor_version = "2.0.3"
1515

1616
repositories {
1717
mavenCentral()
@@ -30,9 +30,11 @@ kotlin {
3030
dependencies {
3131
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
3232
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serialization_version")
33+
3334
api("io.ktor:ktor-client-core:$ktor_version")
34-
api("io.ktor:ktor-client-json:$ktor_version")
3535
api("io.ktor:ktor-client-serialization:$ktor_version")
36+
api("io.ktor:ktor-client-content-negotiation:$ktor_version")
37+
api("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
3638
}
3739
}
3840

0 commit comments

Comments
 (0)