Skip to content

Instantly share code, notes, and snippets.

@revmischa
Created March 11, 2019 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save revmischa/227011f3696e106b36ffac3af45c8c8e to your computer and use it in GitHub Desktop.
Save revmischa/227011f3696e106b36ffac3af45c8c8e to your computer and use it in GitHub Desktop.
Always unwrap a JSON response key using Retrofit/Moshi/Kotlin
// for parsing "data" out of every response object
// https://stackoverflow.com/questions/23070298/get-nested-json-object-with-gson-using-retrofit/40691739#40691739
class ItemTypeAdapterFactory : TypeAdapterFactory {
override fun <T> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T> {
val delegate = gson.getDelegateAdapter(this, type)
val elementAdapter = gson.getAdapter(JsonElement::class.java)
return object : TypeAdapter<T>() {
override fun write(out: JsonWriter, value: T) {
delegate.write(out, value)
}
override fun read(`in`: JsonReader): T {
var jsonElement = elementAdapter.read(`in`)
if (jsonElement.isJsonObject) {
val jsonObject = jsonElement.asJsonObject
if (jsonObject.has("data")) {
jsonElement = jsonObject.get("data")
}
}
return delegate.fromJsonTree(jsonElement)
}
}.nullSafe()
}
}
// request builder
private val client = OkHttpClient().newBuilder()
.addInterceptor(authInterceptor)
.build()
// handle unwrapping
var gson = GsonBuilder()
.registerTypeAdapterFactory(ItemTypeAdapterFactory()) // unwraps "data" object
.create()
// API factory
fun retrofit(baseURL: String) : Retrofit = Retrofit.Builder()
.client(client)
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addConverterFactory(MoshiConverterFactory.create()) // handle serialization and deserialization
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment