Last active
June 5, 2020 09:36
-
-
Save VitaliyBelyaev/31edc50daedbb144941a46c5dfa84b16 to your computer and use it in GitHub Desktop.
Retrofit converter factory wrapper inspired by Jake Wharton presentation https://speakerdeck.com/jakewharton/making-retrofit-work-for-you-ohio-devfest-2016?slide=91
This file contains 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
// Could create in separate file | |
annotation class SomeAnnotation | |
// This annotation should be placed to your Retrofit Api method | |
@GET("api/v1/data/{id}") | |
@SomeAnnotation | |
suspend fun fetchData(@Path("id") id: Int): SomeData | |
class ConverterFactoryWrapper( | |
standardMoshi: Moshi, | |
moshiForSomeAnnotation: Moshi | |
) : Converter.Factory() { | |
private val standardFactory = MoshiConverterFactory.create(standardMoshi) | |
private val someAnnotationFactory = MoshiConverterFactory.create(moshiForSomeAnnotation) | |
override fun responseBodyConverter( | |
type: Type, | |
annotations: Array<out Annotation>, | |
retrofit: Retrofit | |
): Converter<ResponseBody, *>? { | |
return if (containsSomeAnnotation(annotations)) { | |
someAnnotationFactory.responseBodyConverter(type, annotations, retrofit) | |
} else { | |
standardFactory.responseBodyConverter(type, annotations, retrofit) | |
} | |
} | |
// You also should override requestBodyConverter to proxy that call to standart factory | |
override fun requestBodyConverter( | |
type: Type, | |
parameterAnnotations: Array<Annotation>, | |
methodAnnotations: Array<Annotation>, | |
retrofit: Retrofit | |
): Converter<*, RequestBody>? { | |
return standardFactory.requestBodyConverter( | |
type, | |
parameterAnnotations, | |
methodAnnotations, | |
retrofit | |
) | |
} | |
// You also should override stringConverter to proxy that call to standart factory | |
override fun stringConverter( | |
type: Type, | |
annotations: Array<Annotation>, | |
retrofit: Retrofit | |
): Converter<*, String>? { | |
return standardFactory.stringConverter(type, annotations, retrofit) | |
} | |
private fun containsStoreStatusAnnotation(annotations: Array<out Annotation>): Boolean { | |
return annotations.find { it.annotationClass == SomeAnnotation::class } != null | |
} | |
} | |
// Then add this converer wrapper to retrofit when creting it | |
Retrofit.Builder() | |
.baseUrl(BuildConfig.API_BASE_URL) | |
.client(/.../) | |
.addConverterFactory( | |
// In this example Retrofit initialize in Koin appModule | |
ConverterFactoryWrapper(get(named("standard")), get(named("someAnnotaion"))) | |
) | |
.build() | |
.create(Api::class.java) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment