apollo-link-state
apollo-link-state copied to clipboard
Is it possible to lazy load resolvers?
First, Apollo link state is mind-blowing. Once start to use it, don't really want to go back to 'redux-nish' store anymore.
I am working on angular which out of the box provide router-based lazy loading feature. Ngrx which is kind of de facto state management for angular application, also supports lazy loading feature. As a result Angular with ngrx power the fully modularized application structure.
Apollo link state is an awesome library which will be definitely capable of replacing ngrx. Would the lazy loading feature be possible in apollo-link-state or would it be on the road map?
Hey! Thanks for the awesome feedback, I'm glad you're loving apollo-link-state
so far 🎉
Right now, you can lazily write defaults to the store (just call cache.writeData
with your initial state once you transition routes), but there's no way of lazily adding resolvers to your resolver map. Have you experienced any performance issues by specifying all your resolvers up front?
We haven't experienced any performance issues since our application is still in very early stage. Right now we have several teams working on different features of a single application and these features are lazy loaded on demand in order to keep the initiate bundle small. In order to allow the teams work independently, we are looking for the solution of having distributed resolver map or even to be able to lazy load and then concat the resolver map when the corresponding features are lazy loaded.
More than 30% of our application logic is related to local stage and we don't want the initiate bundle getting larger as the application logic is getting complicated.
BTW, @peggyrayzis I like your talks/blogs very much and looking forward to your next new idea of Apollo stack. :muscle:
Lazy loading would be a very impactful addition to apollo-link-state for large teams or modular projects. For instance, in our application every page is lazy loaded (the same rings true for large projects such as Google Cloud Platform which is built on angular). Having feature-specific state logic living with the features is key to separating concerns with different aspects of an application! Would be cool to see this implemented.
Just adding my two cents.
I agree with @goldenbearkin and @jdeanwaite I was actually having a similar discussion on the apollo-angular repo regarding lazy loading.
I have also been reading up issues on the main apollo-client
repo. In particular this thread for the main apollo-client
module seems to imply schema stitching is what the team prefers.
I think this issue might be better placed in that repo, as if you could be lazy when schema stitching
into the main client, this repo would not need to change.
My thoughts:
This is a snippet from my current client setup for Apollo-Angular
const cache = new InMemoryCache();
const remoteHttpLink = httpLink.create({uri});
const stateLinkConfig = {
cache,
defaults: {
...themeDefault,
...searchQueryDefault
},
resolvers: {
Mutation: {
...themeResolverMutation,
...searchQueryResolverMutation,
}
},
};
const stateLink = withClientState(stateLinkConfig);
const apolloLink = ApolloLink.from([
stateLink,
remoteHttpLink,
]);
apollo.create({
link: apolloLink,
cache: cache,
});
Not sure exactly how this would work, but as ApolloLink.from takes an array:
const apolloLink = ApolloLink.from([
stateLink,
remoteHttpLink,
]);
It would be great if you could push/concat extra items into the apollo client asynchronously after creation, something like this:
//totally made up code
const stateLinkConfig2 = {
cache,
defaults: {
...theme2Default,
},
resolvers: {
Mutation: {
...theme2ResolverMutation,
}
},
};
apollo.link.concat(ApolloLink.from([stateLinkConfig2])
@peggyrayzis, @goldenbearkin, @jdeanwaite What do you think, should we open this as issue on the main repo?
@vespertilian I like the idea, though I think adding to the existing link chain may present some issues. For example, I know there are scenarios where the order of the links matter, so if you have a link that should go last and then a lazy-loaded state link is added to the end that could cause undesired behaviors. I think if we could maintain a single link for apollo-link-state and be able to aggregate resolvers onto that, that could be better. Thoughts?
@jdeanwaite
Sure, I mean it's primarily the internal state resolvers and mutations I want to have lazy loaded.
Is this what you were thinking?
const cache = new InMemoryCache();
const remoteHttpLink = httpLink.create({uri});
const stateLinkConfig = {
cache,
defaults: {
...themeDefault,
...searchQueryDefault
},
resolvers: {
Mutation: {
...themeResolverMutation,
...searchQueryResolverMutation,
}
},
};
const stateLink = withClientState(stateLinkConfig);
const apolloLink = ApolloLink.from([
stateLink,
remoteHttpLink,
]);
apollo.create({
link: apolloLink,
cache: cache,
});
//totally made up code that would be lazy loaded
const stateLinkConfig2 = {
cache,
defaults: {
...theme2Default,
},
resolvers: {
Mutation: {
...theme2ResolverMutation,
}
},
};
stateLink.mergeConfig(stateLinkConfig2)
@vespertilian Yeah something like that! Basically a way to merge in the resolvers and ensure that any new defaults get written. Something like this would be super useful, though I'm not 100% sure how easy it is to implement. Including ApolloModule in a lazy loaded module is trouble enough as it is (forced to use an injection token).
Hey! Thanks for your patience. I'm considering adding a way to dynamically load resolvers and defaults for the 1.0 release. I'd love your feedback once I spec it out. 😀
Hey @peggyrayzis just let me know when you have something to look at. Happy to help in any way I can.
@peggyrayzis sounds great! Look forward to seeing progress on this.
Any news or a workaround on this? Thx
@peggyrayzis Also keen to help on this - excited by the idea of lazy-loading resolvers.
As I understand the new feature of the apollo-client of adding resolvers dynamically, as mentioned in https://github.com/apollographql/apollo-client/pull/4338, this will make lazy loading available.
Any good examples out there to demonstrate how lazy loading resolvers work?!