Easy methods to use Retrofit, Moshi, Gson, Kotlin Serialization and Ktor consumer libraries to attach the REST API net service in Android app?
This text was initially printed at vtsen.hashnode.dev on Could , 2022.
I created this easy Android App (written in Kotlin and Jetpack Compose) to assist me to know alternative ways to hook up with REST API net service utilizing completely different HTTP Shopper libraries.
I additionally tried to measure the reminiscence and efficiency of utilizing these libraries.
That is the REST API – Meals Classes from TheMealDB the app tries to retrieve. It returns in JSON format.
The app is carried out with MVVM, however the next solely highlights the steps it is advisable to do to construct these HTTP consumer libraries.
If you wish to know the small print, please confer with the supply code supplied on the finish of this text.
1. Retrofit + Moshi
That is the primary methodology I discovered whereas creating this Asteroid Rader App in certainly one of my Android Kotlin Developer Nanodegree Tasks.
- Retrofit is the HTTP consumer library to hook up with REST API net service
- Moshi is the library to parse JSON response into Kotlin information object
Import Retrofit + Moshi Converter Libraries
def retrofit_version = "2.9.0"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
def moshi_version = "1.12.0"
implementation "com.squareup.moshi:moshi:$moshi_version"
implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
Create Knowledge Class for Moshi
information class MoshiMealCategoriesResponse (
val classes: Listing<MoshiMealCategory>
)
information class MoshiMealCategory(
@Json(title="idCategory") val idCategory: String,
val strCategory: String,
val strCategoryDescription: String,
val strCategoryThumb: String
)
@Json
is Moshi annotation and solely is required in case your val title is completely different from the JSON string.
Outline Retrofit + Moshi API Interface
interface RetrofitMoshiMealsApi {
@GET("classes.php")
droop enjoyable getMealCategories(): MoshiMealCategoriesResponse
}
Construct Retrofit + Moshi API
class RetrofitMoshiMealsWebService {
personal val api: RetrofitMoshiMealsApi by lazy {
createMealsApi()
}
droop enjoyable getMealCategories(): MoshiMealCategoriesResponse {
return api.getMealCategories()
}
personal enjoyable createMealsApi(): RetrofitMoshiMealsApi {
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.construct()
val retrofit = Retrofit.Builder()
.baseUrl(MainRepository.BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.construct()
return retrofit.create(RetrofitMoshiMealsApi::class.java)
}
}
2. Retrofit + Gson
Just like Moshi, Gson is an open-source Java library to serialize and deserialize JSON to Kotlin information objects.
Since Moshi import has already proven above, I am not going to point out right here once more.
Import Gson Converter Library
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
Create Knowledge Class for Gson
information class GsonMealCategoriesResponse (
val classes: Listing<GsonMealCategory>
)
information class GsonMealCategory(
@SerializedName("idCategory") val idCategory: String,
val strCategory: String,
val strCategoryDescription: String,
val strCategoryThumb: String
)
@SerializedName
is Gson annotation, which is analogous to @Json
in Moshi annotation in case your JSON string is completely different from the val title.
Technically I can share the identical information class for all these completely different JSON parser implementation, however I feel it’s cleaner to separate because it requires completely different annotations for various parser libraries.
Outline Retrofit + Gson API Interface
interface RetrofitGsonMealsApi {
@GET("classes.php")
droop enjoyable getMealCategories(): GsonMealCategoriesResponse
}
Construct Retrofit + Gson API
class RetrofitGsonMealsWebService {
personal val api: RetrofitGsonMealsApi by lazy {
createMealsApi()
}
droop enjoyable getMealCategories(): GsonMealCategoriesResponse {
return api.getMealCategories()
}
personal enjoyable createMealsApi(): RetrofitGsonMealsApi {
val gsonConverterFactory = GsonConverterFactory.create()
val retrofit = Retrofit.Builder()
.baseUrl(MainRepository.BASE_URL)
.addConverterFactory(gsonConverterFactory)
.construct()
return retrofit.create(RetrofitGsonMealsApi::class.java)
}
}
3. Retrofit + Kotlin Serialization
Just like Moshi and Gson, Kotlin Serialization is an official Kotlin library which can be utilized to serialize and deserialize JSON to Kotlin information objects.
One of many suggestions I received within the Android Kotlin Developer NonoDegree is to make use of Kotlin Serialization. The reminiscence and efficiency are higher as a result of it would not use reflection.
Add Kotlin Serialization Plugin
Add this in appbuild.gradle
plugins {
...
import venture. id 'org.jetbrains.kotlin.plugin.serialization' model "$kotlin_version"
}
Ensure you replace the construct.gradle
on the app stage and never on the venture stage. If you happen to see this warning under, it’s probably you replace the incorrect construct.gradle
file (i.e. venture stage).
Warning:(5, 1) kotlinx.serialization compiler plugin just isn't utilized to the module, so this annotation wouldn't be processed. Just remember to've setup your buildscript appropriately and re-import venture.
It took me some time to determine I up to date incorrect construct.gradle
. It compiled wonderful however failed at run time. Do not make the identical mistake I did.
Import Kotlin Serialization Library
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2"
Import Kotlin Serialization Converter + okhttp3 Libraries
There isn’t any official Kotlin Serialization Converter for Retrofit from squareup, and we’re utilizing the one from Jake Wharton.
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
implementation "com.squareup.okhttp3:okhttp:4.9.3"
okhttp3
is required for "utility/json".toMediaType()
utilization (see under)
Create Knowledge Class for Kotlin Serialization
@Serializable
information class KotlinSerdesMealCategoriesResponse (
val classes: Listing<KotlinSerdesMealCategory>
)
@Serializable
information class KotlinSerdesMealCategory(
@SerialName("idCategory")
val idCategory: String,
val strCategory: String,
val strCategoryDescription: String,
val strCategoryThumb: String
)
Just like @Json
(Moshi) and @SerializedName
(Gson), @SerialName
is used for Kotlin Serialization. Please observe that it is advisable to annotate the category with @Serializable
with the intention to use the Kotlin Serialization.
Outline Retrofit + Kotlin Serialization API Interface
interface RetrofitKotlinSerdesMealsApi {
@GET("classes.php")
droop enjoyable getMealCategories(): KotlinSerdesMealCategoriesResponse
}
Construct Retrofit + Kotlin Serialization
class RetrofitKotlinSerdesMealsWebService {
personal val api: RetrofitKotlinSerdesMealsApi by lazy {
createMealsApi()
}
droop enjoyable getMealCategories(): KotlinSerdesMealCategoriesResponse {
return api.getMealCategories()
}
@OptIn(ExperimentalSerializationApi::class)
personal enjoyable createMealsApi(): RetrofitKotlinSerdesMealsApi {
val contentType = "utility/json".toMediaType()
val retrofit = Retrofit.Builder()
.baseUrl(MainRepository.BASE_URL)
.addConverterFactory(Json.asConverterFactory(contentType))
.construct()
return retrofit.create(RetrofitKotlinSerdesMealsApi::class.java)
}
}
Please observe that it is advisable to add @OptIn(ExperimentalSerializationApi::class)
with the intention to use the converter library. You additionally want so as to add the opt-in compiler argument in your construct.gradle
module stage file.
android {
...
duties.withType(org.jetbrains.kotlin.gradle.duties.KotlinCompile).configureEach {
kotlinOptions {
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
}
}
4. Ktor Shopper + Kotlin Serialization
Ktor consumer is a multiplatform HTTP consumer library.
Import Ktor Shopper with Kotlin Serialization Libraries
def ktor_version = "1.6.8"
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-cio:$ktor_version"
implementation "io.ktor:ktor-client-serialization:$ktor_version"
Create Ktor Shopper and Implement API Interface
The information class is strictly the identical with the Kotlin Serialization information class above . So I am not going to point out right here once more.
To make use of Ktor Shopper, we do not really want to outline the interface as required by Moshi. You possibly can simply name ktorHttpClient.get("URL right here")
API immediately.
class KtorKotlinSerdesMealsWebService {
personal val ktorHttpClient = HttpClient {
set up(JsonFeature) {
serializer = KotlinxSerializer()
}
}
droop enjoyable getMealCategories(): KotlinSerdesMealCategoriesResponse {
return ktorHttpClient.get("${MainRepository.BASE_URL}classes.php")
}
}
Reminiscence and Efficiency
I added this Allow Efficiency Check
verify field to the primary display. When it’s checked, it can name the API 10 instances for efficiency testing.
I ran some reminiscence and efficiency checks and listed below are the outcomes. I ran a few instances and took the typical. I additionally restarted the app to run HTTLP consumer library independently, so the outcomes will not be overlapped.
HTTP Shopper Library | Reminiscence Utilization | Efficiency |
---|---|---|
Retrofit + Moshi | 22 M bytes | 4.8 seconds |
Retrofit + Gson | 19 M bytes | 4.9 seconds |
Retrofit + Kotlin Serialization | 20 M bytes | 4.9 seconds |
Ktor Shopper + Kotlin Serialization | 22 M bytes | 10.8 seconds |
Reminiscence and efficiency for Retrofit + Gson and Retrofit + Kotlin Serialization are related. Retofit + Moshi makes use of barely extra reminiscence with related efficiency, nevertheless it could possibly be simply false constructive.
However, what occur to Ktor Cilent? Ktor Shopper’s efficiency is round 2x slower!
Conclusion
Earlier than I ran the reminiscence and efficiency, I had an impression Ktor Shopper + Kotlin Serialization should be the most suitable choice, nevertheless it turned out to be worst! Possibly it’s due to multiplatform overhead?
Additionally, the declare for Kotlin Serialization use much less reminiscence and quicker might be not true. It’s about the identical as Moshi and Gson or I didn’t run the take a look at proper?
It is rather apparent the selection is Retrofit.
Personally, I’ll in all probability select
- Moshi over Gson as a result of Moshi is a more recent library than Gson
- Moshi over Kotlin Serialization as a result of Retrofit Kotlin Serialization Converter is NOT an official library(not a part of the squareup libraries).
Given this little analysis that I’ve achieved, my go-to is Retrofit + Moshi.
Supply Code
GitHub Repository: Demo_SimpleRestAPI