Curious if anyone who has started playing around with Apollo has figured out a good way to do activity transitions with dependent data. Lets say I have Activity A with a list of preview data previewList: [{1, a,b}, {2, a,b} ..] and Activity B that shows a detail view detailView: {1, a, b, c ,d}.
How can we smoothly transition from Activity A to Activity B? Let's say we create fragment frag = {#, a, b} and changed Activity B to be {frag ,c, d}. But, when we try to load from cache, it would be a miss, because the root query is different (detailView not previewList), although both are comprised of the same source object. This is a problem if you a relying on a quick load for shared element transitions, or just plain responsiveness on the first load of a page.
Summary of some slack conversations:
Parcleable is bad (transaction too large exception). Let's not enable developers by building it in.
We can flatten the cache store to not have first level QueryRoot. This allows queries that have never run before to be able to resolved if all their data is present in the cache. (Models need to enforce their nullability rules on fields, if a non-null field is null then it's a cache miss).
@BenSchwab: The way Apollo JS solves this is with custom resolvers. Alternatively, you could load a fragment directly from the store by ID, that's what I've been doing in Apollo iOS. That doesn't currently give you query watching however, so I'm in the process of adding the ability to watch arbitrary fragments as well.
@BenSchwab I'm not really sure how you guys come up with that decision but isn't this a user fault if they ever saved the whole response for instance in a bundle across activity changes?
Parcel isn't bad if you know how to use it correctly, yes I know sometimes even when you know how to use it, things might break, but thats not the library problem but user fault, Parcel is one of Android fundamentals to pass an object from an activity to another, while its hard currently to even save the data in a local store to rely on some sort of an ID fetching for instance, there is only one way which is to serialize & deserialize the object using Gson for example to be able to pass it around.
I think this should be by default out of the box as we are dealing with data that it most definitely needed to be passed around.
The rational is mainly that we offer a robust way to efficiently access data from both an in memory cache, and persistent sql cache.
I agree that parcelable isn't inherently bad, but an architecture which uses it to store models can cause problems. Google even went as far as to explicitly say that storing entire models in parcels is dangerous:
For example, if you have a user interface that shows information about a Country, you should never put the Country object into the saved instance state. You can put the countryId into the saved state (unless it is already saved by a View or Fragment arguments). The actual object should live in a database and the ViewModel can retrieve it using the saved countryId.
Enabling this by default seems to us to be an anti-pattern.
Having said that, our goal is to create a great data client, and if you can provide more context on why relying on the caching model is not sufficient, we can reopen this for discussion.
Google even went as far as to explicitly say that storing entire models in parcels is dangerous:
I can't disagree with that, but again, its user fault & not library fault.
why relying on the caching model is not sufficient
Simple use case is Activity transition, more complicated use case is passing for example, a comment object to be edited.
I'm not against the caching module its really great but I thought the library should provide more extension rather than limitation.
If that can't be by default at least maybe to be provided as an extension that can be added or enabled?
What happens when your comment gets too large or android again reduces the size of the bundle? If you really want to do this I recommend to transfer from Apollo domain models to view models which you'll have total control over. (we currently do that in our app). If you are worried about method count you can enable a flag to only generate fields within Apollo.
@digitalbuddha method counts are not a worry for me :p minSDK = 21 with multidex, Android won't reduce the bundle but instead will crash the app, I handle that so if I see that the comment is larger than lets say 500KB(some figure may differ from a device to another) the bundle will automatically be cleared to avoid TTL exception.
I'll try and do the transformation later or better first try out the caching module it might be suitable & less (code to write) than transforming the object to another one.
The caching support is quite robust. We have in me memory guava caching, sql normalized caching and raw http response caching. Would love to hear your feedback!
@digitalbuddha sure, once I get that up and running will update you accordingly. @BenSchwab & @digitalbuddha thanks for your replies & clarification.
Most helpful comment
The rational is mainly that we offer a robust way to efficiently access data from both an in memory cache, and persistent sql cache.
I agree that parcelable isn't inherently bad, but an architecture which uses it to store models can cause problems. Google even went as far as to explicitly say that storing entire models in parcels is dangerous:
Enabling this by default seems to us to be an anti-pattern.
Having said that, our goal is to create a great data client, and if you can provide more context on why relying on the caching model is not sufficient, we can reopen this for discussion.