Closed goa closed 3 years ago
It's not a good idea to mix model objects across serialization formats. You either should persist the raw JSON or split the models for the networking layer and the persistence layer. Changes in schema shouldn't affect JSON serialization. Changes in JSON format shouldn't affect schema.
While I agree that that mixing model objects is not the best approach, it's usually much less work when developing smaller to medium apps. Furthermore, this approach is possible for example with GSON and Realm, since GSON has its own approach for including / excluding fields, but it is impossible with Moshi and Realm since both libraries rely on transient
.
While I understand that transient
is The Right Way, I believe that adding an alternative way to exclude (or force-include transient) fields would be helpful in many situations to save code and increase adoption of Moshi in older projects.
I guess that if there are no other requests for this, the issue could be closed.
I'm really holded back in GSON becouse of this missing feature on Moshi, and I don't want to be like this :'(
Also I would like to have more control over serialization and deserialization differences at runtime, for example, I work with a restfull API that offer data with ID fields, I want to deserialize this field for sync propouses but I don't want to serialize an ID when I post a new object to the API becouse it'll be useless, the API will override the value for obvious reasons.
According to the documentation:
Transient fields are omitted when writing JSON. When reading JSON, the field is skipped even if the JSON contains a value for the field. Instead it will get a default value.
So my
@Exclude(serialize=false, deserialize=true)
can't be safely migrated to Moshi.
You should solve this case in your code base by implementing custom Moshi json adapters for types that need special behavior for different properties.
You should solve this case in your code base by implementing custom Moshi json adapters for types that need special behavior for different properties.
Yes but I'll have to write the serializer by myself in all my datatypes so why do I use Moshi anyway, the idea is to save all the work and with GSON I can saveit
You should solve this case in your code base by implementing custom Moshi json adapters for types that need special behavior for different properties.
I just did this:
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
@Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION)
internal annotation class ID
class IDAdapter {
@ToJson
fun toJson(@ID id: Int): String? = null
@FromJson
@ID
fun fromJson(id: String): Int {
return id.toInt()
}
}
@JsonClass(generateAdapter = true)
data class TestID(
@ID var id: Int,
@Json(name = "name") var nameFiled: String
)
And got my expected result
fun main() {
val dataIn = TestID(
id = 1,
nameFiled = "David"
)
val dataOut = "{\"id\":2, \"name\": \"David\"}"
val moshi = Moshi.Builder()
.add(IDAdapter())
.build()
val adapter = moshi.adapter(TestID::class.java)
val outString = adapter.toJson(dataIn)
println(outString)
val inClass = adapter.fromJson(dataOut)
println(inClass)
}
Output:
{"name":"David"}
TestID(id=2, nameFiled=David)
That would do for now... an annotation preprocessor like @Expose(serialize=false, deserialize=true)
instead of a fixed @ID
for a more flexible field adapter is better, of couse, I'll try to write it down...
As mentioned in the last comments of this issue, other libraries such as Realm and Cupboard are also using
transient
to exclude fields.What if we need a field to be excluded from JSON serialization, but nevertheless be written to the Realm database? If
transient
is used, the field will be excluded from both.I wonder if Moshi could use another dedicated annotation to exclude fields, or at least an annotation to force inclusion of
transient
fields.