When you Retrofit API call, you can pass Enum for parameter

Using Converter, you can convert Enum to String easily

When you Retrofit API call, you want pass Enum class for parameter

But we can use only String for parameter.

So we have to declare value field in Enum class and pass it for parameter. 😥

enum class User(val value: String) {

TED("ParkSangGwon"),

DINO("sjjeong")

}interface ApiService {

@GET("users")

fun getUser(@Query("name") userName: String): Single<MyUser>

}apiService.getUser(User.TED.value)

It’s too cumbersome to declare value field and pass it every time you use it in the API.

(I really hate bothering.😡)

At this time, you can easily convert Enum to String using Retrofit Converter.

(If you don’t know about Retrofit Converter, please refer to the official website.)

If you use Retrofit, you may have added the following libraries as well as retrofit:

implementation 'com.squareup.retrofit2:converter-gson:2.6.2'

or

implementation 'com.squareup.moshi:moshi:1.8.0'

All of these libraries are also built using this Convert.

🔑 Algorithm

We will use the Converter to intercept the data passed to the Enum and convert it into a String.

Determine if type is Class Determine if class is enum Gets a value defined as SerializeName from Enum and returns it

🏭 EnumConverterFactory

First, EnumConverterFactory created with the above algorithm.

class EnumConverterFactory : Converter.Factory() { override fun stringConverter(

type: Type,

annotations: Array<Annotation>,

retrofit: Retrofit

): Converter<Enum<*>, String>? =

if (type is Class<*> && type.isEnum) {

Converter { enum ->

try {

enum.javaClass.getField(enum.name)

.getAnnotation(SerializedName::class.java)?.value

} catch (exception: Exception) {

null

} ?: enum.toString()

}

} else {

null

}

}

You can put this together when building Retrofit.

Retrofit.Builder()

.baseUrl(...)

.addConverterFactory(...)

.addConverterFactory(EnumConverterFactory())

.build()

.create(ApiService::class.java)

🔍 Compare

So let’s compare before and after.

🚫 Before

enum class User(val value: String) {

TED("ParkSangGwon"),

DINO("sjjeong")

}interface ApiService {

@GET("users")

fun getUser(@Query("name") userName: String): Single<MyUser>

}apiService.getUser(User.TED.value)

✅ After

enum class User {

@SerializedName("ParkSangGwon")

TED,

@SerializedName("sjjeong")

DINO

}interface ApiService {

@GET("users")

fun getUser(@Query("name") user: User): Single<MyUser>

}apiService.getUser(User.TED)

The method below is more intuitive and easier to use. 🎉🎉

In many cases, SerializedName is used to map data coming from the server to Enum.

This concept can be added to provide convenient and efficient enum management.

💻 Demo

If you want to check code, visit GitHub Repository below.