This is just a question.
I'm coming from a year's worth of work on a large Relay project. I'm currently exploring Apollo and when I encountered the GraphQL webpack loader, my first thoughts are that it looks great! I see that fragment composition is a new feature to the loader, so perhaps my question is not yet implemented or just the API is not quite solidified yet, etc. Maybe also the workflow is not quite the same as Relay.
With the webpack loader, I have initially been just writing large queries for each of my URL routes. Essentially, I have some "page view" components that all have their own GraphQL query. All data is fetched at that component and passed down to children as props where needed.
As my project is growing, I was going to begin delegating data requirements out to smaller components via fragments. Each component would just define a fragment that requests the needed fields - "the Relay way". Because I've got my GraphQL queries in their own files and webpack goes ahead and compiles them, I appear to lose the ability to compose child fragments into these parent queries, though.
I see that the recently added feature would allow me to #import fragments from within the GraphQL query file, and compose right there, but this is not the same as composing via your tree of child components. This current #import approach requires me to create X number of known parent queries that know which fragments to compose in right then at compile time. Correct?
In the end, I'd still just end up with a specific "master query" for each URL route that composes in whatever fragments I determine I need before-hand, which makes me wonder why even use fragments with this approach? I'd lose the somewhat dynamic composition of the Relay way, with fragments in components and their parents composing them in, right?
This current #import approach requires me to create X number of known parent queries that know which fragments to compose in right then at compile time. Correct?
That's correct, and it's the intended way to use this feature, and you could say GraphQL in general. We've written some blog posts about it: https://dev-blog.apollodata.com/5-benefits-of-static-graphql-queries-b7fa90b0b69a#.m54x4vqj0
I'd lose the somewhat dynamic composition of the Relay way
Relay is also moving away from dynamic composition, in favor of pre-defining these queries in a static way.
why even use fragments with this approach?
Because you get to avoid duplicating the fields a certain component needs if it's used in multiple places. For example:
# Page 1, news feed route
NewsFeed -> PostFeedItem -> PostComments -> Comment
# Page 2, individual post route
PostDetails -> PostComments -> Comment
If you're using the same Comments component in both places, you should define the fields needed by that component in a fragment:
# Fragment for post comments component
fragment PostComments on Post {
comments(first: 10) {
...Comment
}
}
# Fragment for a single comment
fragment Comment on Comment {
author { avatar, name }
content
postedDate
}
Then, you can use these in both of your queries!
query NewsFeed {
newsFeedPosts(first: 10) {
sharedBy { name }
post {
title
...PostComments
}
}
}
query PostDetails {
post(id: $id) {
title
...PostComments
}
}
So what's the point of using a fragment to share it? Well, if you edit the Comment component, you can simply add a few fields to the fragment instead of having to modify a bunch of queries.
It's similar to modules and functions in JavaScript - it helps you organize your code and reduce duplication.
Gotcha. Thanks for the helpful response! 馃憤
Most helpful comment
That's correct, and it's the intended way to use this feature, and you could say GraphQL in general. We've written some blog posts about it: https://dev-blog.apollodata.com/5-benefits-of-static-graphql-queries-b7fa90b0b69a#.m54x4vqj0
Relay is also moving away from dynamic composition, in favor of pre-defining these queries in a static way.
Because you get to avoid duplicating the fields a certain component needs if it's used in multiple places. For example:
If you're using the same
Commentscomponent in both places, you should define the fields needed by that component in a fragment:Then, you can use these in both of your queries!
So what's the point of using a fragment to share it? Well, if you edit the
Commentcomponent, you can simply add a few fields to the fragment instead of having to modify a bunch of queries.It's similar to modules and functions in JavaScript - it helps you organize your code and reduce duplication.