I'm trying to use PolymorphicJsonAdapterFactory
for JSON which provides different structure depending on type
field, like below.
{
"notifications": [
{
"type": "achievement",
"title": "New Achievement!",
"content": "You got new achievement Level 100! (100pt)"
"metadata": {
"category": "level",
"id": "level100",
"points": 100,
}
},
{
"type": "message",
"name": "message",
"content": "Cloud: hello, ~"
"metadata": {
"from": "Cloud",
"content": "hello, ~ "
}
},
{
"type": "new", <--- e.g. this is unknown type for app
"name": "something new",
"content": "You are informed something about. Please check app://~",
"deeplink": "app://~"
}
]
}
Suppose our app already prepared for some known type
, achievement
and message
. But there's a chance to add new type, in this case new
. At this time, we want app to work with minimum properties title
and content
. In short, I want map that new
type to Other
fallback class.
data class Notifications(
val notifications: List<Notification>
)
sealed class Notification {
abstract val type: String
abstract val title: String
abstract val content: String
}
data class Achievement(
override val type: String,
override val title: String,
override val content: String,
val metadata: Metadata,
): Notification() {
data class Metadata(
val category: String,
val id: String,
val points: Int,
)
}
data class Message(
override val type: String,
override val title: String,
override val content: String,
val metadata: Metadata,
): Notification() {
data class Metadata(
val from: String,
val content: String,
)
}
// Any unknown `type` goes here.
data class Other(
override val type: String,
override val title: String,
override val content: String,
): Notification()
val moshi = Moshi.Builder()
.add(
PolymorphicJsonAdapterFactory.of(Notification::class.java, "type")
.withSubtype(Achievement::class.java, "achievement")
.withSubtype(Message::class.java, "message")
.withFallbackJsonAdapter(...)
)
.addLast(KotlinJsonAdapterFactory())
.build()
If moshi configuration and Notification
is so simple like this, it is able to write .withFallbackJsonAdapter(object: Adapter()...)
.
But if we have some customization in Moshi.Builder
, we may want to use adapter from configured moshi val adapter = moshi.adapter()
so we can't write adapter inline. Then, I thought creating two moshi like this.
val moshiWithoutPoly = Moshi.Builder()
// some other base configuration going here
.build()
val moshi = moshiWithoutPoly.newBuilder()
.add(
PolymorphicJsonAdapterFactory.of(Notification::class.java, "type")
.withSubtype(Achievement::class.java, "achievement")
.withSubtype(Message::class.java, "message")
.withFallbackJsonAdapter(moshiWithoutPoly.adapter(Other::class.java) as JsonAdapter<Any>)
)
.build()
Is it fine or is there more proper solution for this?
(Or I'm wondering if it is eligible for proposing new API like .withFallbackSubtype(Other::class.java)
or .withFallbackAdapterFactory(factory)
for such situation.)
from Moshi: How to provide adapter for PolymorphicJsonAdapterFactory.withFallbackJsonAdapter while configuring Moshi.Builder
No comments:
Post a Comment