This is an add-on to Moshi which allows
- to programmatically define mapping between models & JSON
- to keep your models pristine => free of annotations & only concerned about the business logic
It is pretty easy to define the mappings!
data class User(val name: String, val age: Int)
class UserMapper : Mapper<User>() {
val name = field(User::name, "user_name")
val age = field(User::age, "user_age")
override fun create(value: Value<User>) = User(value of name, value of age)
}
Once the mappings have been defined, Moshi
has to be taught about these
val factory = PristineModelsJsonAdapterFactory.Builder()
.add(User::class.java, UserMapper()) // there is an API to allow lazy initialization of mappers too
.build()
val moshi = Moshi.Builder()
.add(factory)
// anything else you wanna teach moshi about
.build()
Voila! Now Moshi
knows how to map User
to/from this JSON
{
"user_name": "John Muir",
"user_age": 76
}
This raises some questions:
- What if the models are written in
Java
? - What if the models have private properties?
Well, there is a way to handle those situations too (considering there are public getters & and a public constructor). Let us consider that the same User
model we saw above is now written in Java
. The mapping is a little bit more involved, but nevertheless possible
class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
class UserMapper : Mapper<User>() {
val name = field("user_field", false, object : PropertyExtractor<User, String> {
override val type: Type = String::class.javaObjectType
override fun extractFrom(t: User): String = t.getName()
})
val age = field("user_age", false, object : PropertyExtractor<User, Int> {
override val type: Type = Int::class.javaPrimitiveType!!
override fun extractFrom(t: User): Int = t.getAge()
})
override fun create(value: Value<User>): User {
return User(value of name, value of age)
}
}
Jitpack the code,
Visit https://jitpack.io/#jayrave/moshi-pristine-models and get the latest version
If you like keeping your models clean, you may be interested in checking out another library => Falkon (Disclaimer: I am the author), which helps to keep your models free of database/ORM specific annotations. Like this library, Falkon also enables to programmatically define the mapping between models & database records