Reputation: 19561
I've read the material but I still don't get it.
This example route appears:
var profileRoute = {
queries: {
// Routes declare queries using functions that return a query root. Relay
// will automatically compose the `user` fragment from the Relay container
// paired with this route on a Relay.RootContainer
X: () => Relay.QL`
# In Relay, the GraphQL query name can be optionally omitted.
query { user(id: $userID) }
`,
},
params: {
// This `userID` parameter will populate the `$userID` variable above.
userID: '123',
},
// Routes must also define a string name.
name: 'ProfileRoute',
};
(I've intentionally replaced user
with X
above where it has no effect on the resulting GraphQL query in order to ensure it has no effect on the graphql composition)
And it would be paired with this container:
module.exports = Relay.createContainer(ProfilePicture, {
// Specify the initial value of the `$size` variable.
initialVariables: {
size: 32
},
// For each of the props that depend on server data, we define a corresponding
// key in `fragments`. Here, the component expects server data to populate the
// `X` prop, so we'll specify the fragment from above as `fragments.X`.
fragments: {
X: () => Relay.QL`
fragment on User {
profilePhoto(size: $size) {
uri,
},
}
`,
},
});
This is probably going to compose into something like this:
query {
user(id: $userID) {
profilePhoto(size: $size) {
uri
}
}
}
But what's the logic here? Perhaps it gets the type User
from the fragment and then looks for a way to get to that type as a direct descendant of something matched in the query? That is, it knows from compiling GraphQL that in query { user(id: $userID) { X } }
X marks the spot where a user type can be found.
So far the only examples I've seen have an extremely simple linear query in the router. Can it be more complex? What happens if you make a query that goes off in two different directions and ends up approaching two different sources of User objects? How could it know which one you wanted? I assume queries like this are not allowed. I also assume that the only place it looks in these queries is the deepest point, so if your router query was something like query { user(id: "52") { bestFriend } }
where bestFriend is also a user, it would give you bestFriend instead of user 52.
Is it even allowed to have a query with more than one level of depth in it though? I tried it, and I got this error:
Invariant Violation: Relay.QL: Expected query
user
to be empty. For example, usenode(id: $id)
, notnode(id: $id) { ... }
Perhaps routes are more simplistic than I thought? Maybe a depth of one level is all you can do?
Upvotes: 1
Views: 786
Reputation: 44
The composition is more simplistic than you thought. Queries can only have a depth of one level, and the fragment on the composed component by the same name (e.g. in this case X
) is essentially spread (...fragment
) into it.
Relay could theoretically support arbitrarily complex queries, but the existing solution has so far been sufficient. This is because arbitrarily complex queries can be broken down into a simply query and a new top-level component.
I also assume that the only place it looks in these queries is the deepest point [...]
This is a neat idea, though.
Upvotes: 1