-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
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
[Kotlin Multiplatform] Update and fixes for Kotlin 1.5.10 and Kotlinx.serialization 1.2.1 #9755
[Kotlin Multiplatform] Update and fixes for Kotlin 1.5.10 and Kotlinx.serialization 1.2.1 #9755
Conversation
…x.serialization 1.2.1 * remove @serializable from interfaces * Using 'String(CharArray): String' is an error. Use CharArray.concatToString() instead * Fix, RequestConfig needs a type to infer type variable T Fixes from @DevSrSouzaern * Fix `private` keyword not being handle as a reservedWords * Fix enum serialization generation * Migrate gradle build to Kotlin DSL
Someone an idea why CircleCi fails? |
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.
Hi @837 since I don't have much experience with kotlin multiplatform I left some comments to try to understand the changes.
httpClientEngine: HttpClientEngine? = null, | ||
jsonConfiguration: JsonConfiguration = JsonConfiguration.Default | ||
) : this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration))) | ||
jsonSerializer: Json |
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.
@837 could you please explain why the change from KotlinxSerializer to Json?
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.
The creation of the KotlinxSerializer is now lazily done in the ApiClient::class.
The Json is used to pass down settings as they might vary depending on the api:
Json {
isLenient = true
ignoreUnknownKeys = true
}
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.
Now when instantiating some Api
class, it's needed to pass jsonSerializer
. It wasn't needed before this PR (jsonConfiguration: JsonConfiguration = JsonConfiguration.Default
in the constructor that was removed), so I think that we should remain backward-compatible here and some kind of a sane default Json
configuration would be good. Best if this default configuration is accessible for the client, so that they can customize it by building upon the default one.
I agree that e.g. ignoreUnknownKeys = true
should be in this default. Otherwise if the service being called starts including some new properties, JSON deserialization will fail. No experience/opinion on isLenient
.
modules/openapi-generator/src/main/resources/kotlin-client/libraries/multiplatform/api.mustache
Show resolved
Hide resolved
...rc/main/resources/kotlin-client/libraries/multiplatform/infrastructure/ApiClient.kt.mustache
Show resolved
Hide resolved
I'm not a kotlin multiplaform users, but I don't see nothing wrong here. |
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.
Thanks for opening this PR! I started one myself (#9827) but it's so similar to yours that I'm happy to help you polish this one :)
As a smoke test, I cloned your repo and branch, and generated a client for my company's internal service. For an example call, it works good!
Apart from the comments I placed inline, let me repeat concerns that I have for my PR:
- are there any end-to-end tests that actually try to call the Petstore service with the generated module? Ideally we'd like to test various edge cases in an automated and repeatable way
- how to ensure there are no regressions in other Kotlin templates that reuse the shared pieces of template?
- is
master
the right target branch for this change, given it's formally backward-incompatible? The policy is confusing to me
.../openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java
Outdated
Show resolved
Hide resolved
modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
Show resolved
Hide resolved
} | ||
|
||
private fun RequestConfig.updateForAuth(authNames: kotlin.collections.List<String>) { | ||
private fun <T: Any?> RequestConfig<T>.updateForAuth(authNames: kotlin.collections.List<String>) { | ||
for (authName in authNames) { | ||
val auth = authentications?.get(authName) ?: throw Exception("Authentication undefined: $authName") | ||
auth.apply(query, headers) |
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.
A comment to line which mentions ktorio/ktor#851 and the below workaround (I cannot place a comment there 😞): how about removing this workaround? I see that this issue was resolved 2 years ago, so the newest version of Ktor almost for sure doesn't have this issue. On the other hand, to keep the number of changes minimal, I'm fine with doing it as a follow-up.
modules/openapi-generator/src/main/resources/kotlin-client/README.mustache
Outdated
Show resolved
Hide resolved
httpClientEngine: HttpClientEngine? = null, | ||
jsonConfiguration: JsonConfiguration = JsonConfiguration.Default | ||
) : this(baseUrl, httpClientEngine, KotlinxSerializer(Json(jsonConfiguration))) | ||
jsonSerializer: Json |
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.
Now when instantiating some Api
class, it's needed to pass jsonSerializer
. It wasn't needed before this PR (jsonConfiguration: JsonConfiguration = JsonConfiguration.Default
in the constructor that was removed), so I think that we should remain backward-compatible here and some kind of a sane default Json
configuration would be good. Best if this default configuration is accessible for the client, so that they can customize it by building upon the default one.
I agree that e.g. ignoreUnknownKeys = true
should be in this default. Otherwise if the service being called starts including some new properties, JSON deserialization will fail. No experience/opinion on isLenient
.
* sample update * revert non multiplatform kotlinx_serialization removal * default Json{} in ApiClient * revert accidental version push for jvm client * Match ktor and Kotlinx Serialization version in documentation and build.gradle.kts
...rc/main/resources/kotlin-client/libraries/multiplatform/infrastructure/ApiClient.kt.mustache
Outdated
Show resolved
Hide resolved
...tlin-multiplatform/src/commonMain/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
Outdated
Show resolved
Hide resolved
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.
LGTM - I think we can merge as is because it works fine, and then apply any improvements like end-to-end tests or code cleanup as follow-ups.
@837 could you please close and reopen this PR to restart CI? Thanks |
Sorry if I miscommunicated, but to restart the CI you could just close and reopen the same PR, there is no need to create a new one. |
Oh didnt know that. Makes more sense to keep this one. |
Looks good to me 👍 |
@837 can you please resolve the merge conflicts when you've time? |
Kotlin tests pass via #9883 |
This dependency was accidentally removed in PR OpenAPITools#9755 where we switched from `build.gradle` to `build.gradle.kts`.
This dependency was accidentally removed in PR #9755 where we switched from `build.gradle` to `build.gradle.kts`.
I had to use a custom mustache template for package {{packageName}}.auth
import io.ktor.util.InternalAPI
import io.ktor.util.encodeBase64
/**
* Custom Template
*/
class HttpBasicAuth : Authentication {
var username: String? = null
var password: String? = null
@OptIn(InternalAPI::class)
override fun apply(query: MutableMap<String, List<String>>, headers: MutableMap<String, String>) {
if (username == null && password == null) return
val str = (username ?: "") + ":" + (password ?: "")
val auth = str.encodeBase64()
headers["Authorization"] = "Basic $auth"
}
}
Because with AS Artic Fox 2020.3.1 Patch 2 With this configuration object Versions {
const val iosTestTask = false
const val foo = "8.6.8"
const val kotlin = "1.5.31"
// Gradle
const val androidGradlePlugin = "7.0.2"
const val gradle = "gradle-7.2-bin"
// Android
const val compileSdk = 30
const val minSdk = 23
const val targetSdk = compileSdk
// You can also use this to specify versions for dependencies. Having consistent
// versions between modules can avoid behavior conflicts.
const val sqldelight = "1.5.1"
const val settings = "0.8"
const val serialization = "1.2.2"
// https://kotlinlang.org/docs/mobile/concurrency-and-coroutines.html#multithreaded-coroutines
const val coroutines = "1.5.1-native-mt"
const val ktor = "1.6.3"
const val openapigen = "5.2.1"
} I had (using e: Opt-in requirement marker annotation on override requires the same marker on base declaration I'd to use |
@shadowsheep1 could you please add a PR with those changes? |
@4brunu sure 👍 |
Fixes from @DevSrSouzaern #9232
Seemed not to be updated anymore.
private
keyword not being handle as a reservedWordsPR checklist
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*
.For Windows users, please run the script in Git BASH.
master
,5.1.x
,6.0.x
@jimschubert , @dr4ke616, @karismann, @Zomzog, @andrewemery, @4brunu, @yutaka0m