-
Notifications
You must be signed in to change notification settings - Fork 722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow access to JSON used in deserializing GraphQL structs and GraphQLResultReader subclassing #30
Comments
@xiekevin: We definitely want to support caching as part of the framework, so it would be great to hear more about what you are currently doing, and how we can make that work in a more structured way. Design input is very welcome! My idea is roughly that the resolver function passed to The |
Hi martijn, thanks for the quick response. What you've described is conceptually in line with what I'm doing, but since I was working under the assumption that Apollo-iOS would be a thin data-fetching layer, I built most of the caching / data-sync outside of the framework. That's probably why the structure is bit messier, I hadn't thought of adding integration to the framework itself. I like the idea of having the resolver update the cache after reading the network response and think it probably makes the most sense to do it there. I am currently using the field value Since I've done it outside the framework, I'm updating the cache when the network returns All the data sync happens through a pub sub implementation that wraps around I use One major issue I've encountered is when arrays of objects are merged together which do not have the full data needed for deserialization. In this case I would like some version of
In this case when the objects are merged, some objects will have both I think what you're proposing sounds stellar. I have a couple questions as someone new to the field of software engineering and especially to design architecture.
Thank you for working on apollo-ios, it's definitely a great tool and has been fun to work with. I'm excited to see it grow more in the future :) |
Thanks for the detailed response! This is exactly the kind of design discussion I was hoping for. What you're describing is pretty much what I had in mind. Your The store is then responsible for merging the new record set with what's already there, and notifying subscribers. It would be great to keep track of dependencies and make this as fine grained as possible, so we don't notify subscribers if their data hasn't changed. I'm not sure what you mean by:
I'm also not sure about these questions. Could you elaborate on what you mean by 'JSON merging' and 'cacheing at the query level'?
Caching lists is definitely one of the most tricky parts! I don't think skipping objects that miss fields is something you want as a default policy, but a lot of this is application-specific, so we want to make sure we expose the right hooks. An argument like So I think the default caching policy wouldn't actually suffer from the problem you're describing. But of course, in many cases we actually want to capture the fact that these lists are part of the same (conceptual) list. If we've already asked for Apollo Client (for JavaScript) gives you a lot of freedom to configure application-specific behavior, and exposes functions like I would also highly recommend this talk by Joe Savona, who works on Relay at Facebook. He presents a really nice summary of the lessons they have learned at Facebook, and that includes a conceptual model for how they do caching and deal with paginated lists. I like the I'm planning on working on this over the next few weeks, and would like to have a basic implementation of caching done by the end of the year. So let's definitely continue this conversation, and maybe there is an opportunity to work together on this, or even adapt some of the code you've been working on. |
Thanks for the thoughtful follow-up, I feel like I'm learning a lot by discussing this thoroughly with you. I feel the general implementation strategy that we've each come up with is identical in most aspects and I think that's a great sign. As for the discussion around syncing at the query level, I had previously been syncing objects themselves and reloading individual objects using To give some context around JSON merging, I've used JSON as the basis of merging or updating records. I wasn't sure how else to do this using object types in Swift since I couldn't figure out a way to set properties dynamically without bridging to use Obj-C's I watched the talk by Joe Savona and it mentions a lot of good points and things I hadn't considered and is definitely a good overview of GraphQL best practices--I'll be sure to forward that to my team. You also brought up many good points about caching lists and I do agree and see now that a lot of it is platform or product specific. As you mentioned earlier about exposing the right hooks, it would definitely be great to be able to fine-tune how the updates occur. With that said, I still have a couple of uncertainties. I now understand that there's no special meaning on
If you have the time it would be great to keep in touch and it's nice to hear that you'll be working on it starting so soon. My implementation is very rough in general so it probably wouldn't be helpful, but would be happy to share if you'd like to take a look! |
@xiekevin: Sorry, I've been preoccupied for a few days, but getting back to this now. I hope to have some code to share soon. To answer your question, fields are not cached based on the response name (that could be an alias), but on a combination of the field name and arguments. The idea here is that fields are basically functions, and different arguments may give different results, so they should be cached separately. In the Star Wars schema for example, you don't want to confuse This means In general, using |
Ah, I get it now, that was a great explanation. Thanks for taking the time to help me understand this caching / synchronization strategy. I'll wait for when you have some code to share to give any further thoughts. Please keep me updated when you have new developments to share! |
@xiekevin: Hey, I just wanted to mention normalized caching has been merged! Still working on updating the documentation and writing a blog post, but it would be great to get some feedback and see if this covers your use cases. |
I'm opening this issue to ask whether the following could be supported:
GraphQLResultReader
To give some context, I'm attempting to create a data synchronization layer on top of GraphQL queries. At a high level, I'm storing the original JSON, updating that JSON when queries to the server return new values, alerting GraphQL structs that their properties have changed, and recreating the object using the reader and updated JSON. I've hacked something together to achieve this, namely:
GraphQLResultReader
initializer publicresponseName
inField
publiccurrentObject
inGraphQLResultReader
publicI think there's probably a better way to do what I want with the library's general purpose in mind, and would like to see if something like this would be able to be supported in an official capacity.
Would either of the above asks be possible to support? If you think that this would be helpful to have, I'm also happy to attempt a PR.
The text was updated successfully, but these errors were encountered: