After talking to several current users of Apollo, we realized that we need to expose some ways to interact with the store without having to understand the normalization that Apollo performs internally.
Providing a way to read an object out of the store given that object's id is one of the easiest and immediately beneficial things to implement.
Suppose we have some user that we fetch using the following GraphQL query at some point in the lifetime of the application:
query {
user {
name
friends {
name
}
id
__typename
}
}
We then assign the dataIdFromObject associated with this object to userId. If we have a userId, we should be able to call client.readObjectWithId(userId) to get the user object associated with that id. This should be a "deep read", i.e. the returned object should look something like this:
{
name: "John Smith",
friends: [
{
name: "Brad Pitt",
},
{
name: "Angelina Jolie",
}
]
}
As a result of implementing this, the application developer can read stuff out of the store without needing a query or any knowledge of how the data is normalized within the store.
What are some of the use cases or reasons that need the exposing of single objects in the store? I can imagine what could be wanted, just would like to understand better.
I personally think this feature needs more consideration, because, from what I understand of Apollo and its usage of Redux, there is nothing in place guaranteeing the validity of the data being read from the store, when it isn't done through a proper GraphQL query, which hits a server first. So, it seems this is basically opening the door to letting the UI show out-of-date/ out-of-sync data, which should be a no-go.
Scott
Yeah that's the whole point of caching though, which is that you intentionally show possibly outdated information to save on network and server resources.
To add to what @stubailo said, we can force-sync data to the server using a refetch.
A common usecase would be fetch some data from the server and then perform set of operations on it before showing some part of it to the user. The point of this feature is just to allow the application developer to peek into the store more closely than just fetching stuff from it using a query.
I'm not sure if it's better to comment on this or the PR, but I have some concerns about this design - specifically I think it should take a GraphQL fragment as an argument.
Yeah that's the whole point of caching though, which is that you intentionally show possibly outdated information to save on network and server resources.
Agreed, though who really wants to show outdated data in most cases? Probably no one. I can see this only useful for data that is very personalized.
I looked through the docs, but couldn't find anything. Does Apollo have a similar subscription system to sync the store with updated data from the server like Relay does?
http://graphql.org/blog/subscriptions-in-graphql-and-relay/
If it did, I'd be much less concerned. :smile:
Or even a TTL, which means any new query for the object in the store would first be concerned if the TTL is active. If not, the query has to be routed to the server. A blank check into a most likely outdated data source is allowing for a lot of trouble up front (pun not intended). :smile:
I guess I don't have an issue with the possibility of grabbing data from the store first. In fact, that is what should be happening. But then, it should be up to Apollo to make sure the data is as up-to-date as possible through conventions set up within Apollo. I don't think it should be left up to the developers to have to fight with data staleness, if Apollo is the one governing the data. :smile:
Scott
BTW Relay doesn't actually support subscriptions right now (that blog post just talks about a plan to support it). That's something we are actively experimenting with, however, so realtime data might be something coming very soon - ideally within the month we'll have a working demo.
A TTL approach would be helpful as well.
Basically right now we (and Relay as well) require the developer to manually manage the state of the cache and decide when to fetch new or outdated data, but I agree there should be something better.
This is going to be a core part of our new store API. It will let you read from the store by providing an ID and a fragment like so:
store.read(objectId, gql` ... on Item { name age }`);
Most helpful comment
This is going to be a core part of our new store API. It will let you read from the store by providing an ID and a fragment like so: