[REQ] [kotlin-client] Support parsing `java.net.URI` with moshi
Created by: chigichan24
Is your feature request related to a problem? Please describe.
Now, Moshi is not supported by parse java.net.URI.
So, if your request or response parameters defined as java.net.URI
, generated apiClient throws an exception like as below.
Caused by: java.lang.IllegalArgumentException: Platform class java.net.URI requires explicit JsonAdapter to be registered
for class java.net.URI
for java.util.List<java.net.URI> photoUrls
for class net.chigita.openapigenexample.gen.pet.model.Pet
at com.squareup.moshi.Moshi$LookupChain.exceptionWithLookupStack(Moshi.java:388)
at com.squareup.moshi.Moshi.adapter(Moshi.java:157)
at com.squareup.moshi.Moshi.adapter(Moshi.java:105)
at com.squareup.moshi.Moshi.adapter(Moshi.java:74)
at com.squareup.moshi.CollectionJsonAdapter.newArrayListAdapter(CollectionJsonAdapter.java:54)
at com.squareup.moshi.CollectionJsonAdapter$1.create(CollectionJsonAdapter.java:38)
at com.squareup.moshi.Moshi.adapter(Moshi.java:145)
at com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory.create(KotlinJsonAdapter.kt:262)
at com.squareup.moshi.Moshi.adapter(Moshi.java:145)
at com.squareup.moshi.Moshi.adapter(Moshi.java:105)
at retrofit2.converter.moshi.MoshiConverterFactory.responseBodyConverter(MoshiConverterFactory.java:89)
at retrofit2.Retrofit.nextResponseBodyConverter(Retrofit.java:362)
at retrofit2.Retrofit.responseBodyConverter(Retrofit.java:345)
at retrofit2.HttpServiceMethod.createResponseConverter(HttpServiceMethod.java:124)
... 12 more
Caused by: java.lang.IllegalArgumentException: Platform class java.net.URI requires explicit JsonAdapter to be registered
at com.squareup.moshi.ClassJsonAdapter$1.create(ClassJsonAdapter.java:75)
at com.squareup.moshi.Moshi.adapter(Moshi.java:145)
here is a sample project.
But in the context of multiplatform, UriAdapter is supported (link). So how about add UriAdapter for MoshiBuilder
Describe the solution you'd like
To resolve this issue, we have to two changes.
- Fix
modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/URIAdapter.kt.mustache
package {{packageName}}.infrastructure
{{#kotlinx_serialization}}
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
{{/kotlinx_serialization}}
{{#moshi}}
import com.squareup.moshi.FromJson
import com.squareup.moshi.ToJson
{{/moshi}}
import java.net.URI
{{#moshi}}
{{#nonPublicApi}}internal {{/nonPublicApi}}class UriAdapter {
@ToJson
fun toJson(uri: URI) = uri.toString()
@FromJson
fun fromJson(s: String) = URI.create(s)
}
{{/moshi}}
{{#kotlinx_serialization}}
@Serializer(forClass = URI::class)
object UriAdapter : KSerializer<URI> {
override fun serialize(encoder: Encoder, value: URI) {
encoder.encodeString(value.toASCIIString())
}
override fun deserialize(decoder: Decoder): URI = URI(decoder.decodeString())
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("URI", PrimitiveKind.STRING)
}
{{/kotlinx_serialization}}
- Fix
modules/openapi-generator/src/main/resources/kotlin-client/jvm-common/infrastructure/Serializer.kt.mustache
@JvmStatic
val moshiBuilder: Moshi.Builder = Moshi.Builder()
.add(OffsetDateTimeAdapter())
.add(LocalDateTimeAdapter())
.add(LocalDateAdapter())
.add(UUIDAdapter())
.add(ByteArrayAdapter())
{{^moshiCodeGen}}
.add(KotlinJsonAdapterFactory())
{{/moshiCodeGen}}
.add(BigDecimalAdapter())
.add(BigIntegerAdapter())
.add(UriAdapter()) // Add this line
Describe alternatives you've considered
Just use --type-mapping
option