Created
January 5, 2025 16:04
-
-
Save cbeyls/dac2023d390696f87ff8265c025fb2a5 to your computer and use it in GitHub Desktop.
A Retrofit Converter.Factory using the Json format from the Kotlin Serialization library, optimized to stream response bodies
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package be.digitalia.retrofit2 | |
import kotlinx.serialization.DeserializationStrategy | |
import kotlinx.serialization.ExperimentalSerializationApi | |
import kotlinx.serialization.SerializationStrategy | |
import kotlinx.serialization.json.Json | |
import kotlinx.serialization.json.decodeFromStream | |
import kotlinx.serialization.serializer | |
import okhttp3.MediaType.Companion.toMediaType | |
import okhttp3.RequestBody | |
import okhttp3.RequestBody.Companion.toRequestBody | |
import okhttp3.ResponseBody | |
import retrofit2.Converter | |
import retrofit2.Retrofit | |
import java.lang.reflect.Type | |
/** | |
* A Retrofit Converter.Factory using the Json format from the Kotlin Serialization library, | |
* optimized to stream response bodies. | |
*/ | |
@OptIn(ExperimentalSerializationApi::class) | |
internal class JsonStreamingFactory( | |
private val serializer: Json | |
) : Converter.Factory() { | |
override fun responseBodyConverter( | |
type: Type, | |
annotations: Array<out Annotation>, | |
retrofit: Retrofit | |
): Converter<ResponseBody, *> { | |
val loader: DeserializationStrategy<Any> = serializer.serializersModule.serializer(type) | |
return Converter { responseBody -> | |
responseBody.use { | |
serializer.decodeFromStream(loader, responseBody.byteStream()) | |
} | |
} | |
} | |
override fun requestBodyConverter( | |
type: Type, | |
parameterAnnotations: Array<out Annotation>, | |
methodAnnotations: Array<out Annotation>, | |
retrofit: Retrofit | |
): Converter<*, RequestBody> { | |
val saver: SerializationStrategy<Any> = serializer.serializersModule.serializer(type) | |
return Converter<Any, RequestBody> { value -> | |
serializer.encodeToString(saver, value).toRequestBody(MEDIA_TYPE) | |
} | |
} | |
companion object { | |
private val MEDIA_TYPE = "application/json; charset=UTF-8".toMediaType() | |
} | |
} | |
@JvmName("create") | |
fun Json.asStreamingConverterFactory(): Converter.Factory { | |
return JsonStreamingFactory(this) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment