Reputation: 2510
I am looking for help regarding best practice using Apollo, React and Meteor.
I linked the Meteor.user() model to a Schema in Apollo and I can now access it thanks to a Query Component. I have a query that looks like this :
gql`
query User {
user {
_id,
email
}
}
`
and it does the job, with a resolver giving directly the email adress. However I need it in different places and for every component where I need it I am making another < Query >
component with the same Query I copy paste from on file to another. It seems to me that I am loosing the all point if many of my components are querying again and again the same things. However I do not manage to find the solution to this "DRY" problem. There are not yet so many examples including the Query component from react apollo so if someone could help me with this it'd be much appreciated.
Upvotes: 2
Views: 2573
Reputation: 84667
By default, the Apollo client uses a fetchPolicy
of cache-first
. That means if the result of the query is already in the cache, it will be fetched from there and no network request will be made. That allows you to use the same query across multiple Query
components without having to worry about making the same request to your server over and over again.
You can specify the fetchPolicy
for a particular Query component if you want to override this default behavior -- for example, maybe you want to always fetch new data from the server, in which case you would use network-only
or maybe cache-and-network
. See the docs for more details.
NOTE: A common "gotcha" is that the cache uses the id
(or _id
) field to normalize the cached results. That means your queries have to include the id
field (or provide a custom implementation of dataIdFromObject
) to see the expected behavior. See this page for additional details.
In terms of keeping things dry, it's common practice to store your queries in one or more separate modules and then import them as needed. So you could have a queries.js
file like this:
import gql from 'graphql-tag'
export const USER_QUERY = gql`
query User {
user {
_id,
email
}
}
`
graphql-tag
comes with a loader that lets you import queries directly from .graphql/.gql files if you're using Webpack. Check out the recipe here. There's also a babel plugin for doing effectively the same thing (checkout it out here). Any of these approaches should reduce the redundancy in your code.
EDIT: As pointed out in @camba1's answer, fragments can also be used to DRY up your queries:
query User {
user {
...userFields
}
}
fragment userFields on User {
_id,
email,
}
Upvotes: 3
Reputation: 1820
Another thing that may be useful to avoid having to copy paste query code all over the place is to use query fragments .
for example:
# Query that contains a fragment
query myQuery1($_key: ID!) {
myQuery1(_key: $_key) {
field1,
...myFragmentFields
}
}
# Fragment to be used in queries
fragment myFragmentFields on myQueryType {
_key,
name,
formula,
type
}
Here is the documentation:
Upvotes: 2