问题
I started out with the relay-starter-kit
and also worked my way through the Relay and GraphQL documentation. But there are quite a few areas that are unexplained and mysterious.
Seriously I read a lot of documentations everywhere about all these things but couldn't find any satisfying explanations for the following questions:
What is this for? I put logging but it never even gets called at all:
var {nodeInterface, nodeField} = nodeDefinitions(
(globalId) => {
var {type, id} = fromGlobalId(globalId);
if (type === 'User') {
return getUser(id);
} else if (type === 'Widget') {
return getWidget(id);
} else {
return null;
}
},
(obj) => {
if (obj instanceof User) {
return userType;
} else if (obj instanceof Widget) {
return widgetType;
} else {
return null;
}
}
);
And what is the actual effect of this:
interfaces: [nodeInterface],
Maybe related to that, what does the node
field here do:
var queryType = new GraphQLObjectType({
name: 'Query',
fields: () => ({
node: nodeField,
// Add your own root fields here
viewer: {
type: userType,
resolve: () => getViewer(),
},
}),
});
And what is the magic around the id
field? What is globalIdField
for?
I have an id
in my database and thought I could use it in my GraphQL objects:
Instead of:
id: globalIdField('User'),
I want to use my database id:
id: {
type: GraphQLID,
description: 'The identifier'
},
But if I do that I get an error in the browser saying RelayQueryWriter: Could not find a type name for record '1'
.
I can get rid of that error by adding __typename
to my component containers Relay Query but that seems all wrong.
It would be great if you could give some deeper insides and a better explanation here and enhance the official documentation.
Thank you
回答1:
The Node
root field, in combination with globally unique IDs, comes into play when Relay needs to refetch an object. Refetching occurs when you call this.props.relay.forceFetch()
or when you add fields to the query for an object whose global ID is known because it has already been partially fetched.
In cases like these, Relay will short circuit the regular query and execute a query for the object(s) directly using its global ID and the node
root call.
Example:
Assume that $showComments
was false
when this query was first resolved.
query {
viewer {
stories(first: 10) {
edges {
node {
id,
comments(first: 10) @include(if: $showComments) {
author,
commentText
}
text,
}
}
}
}
}
This will have caused a fetch for id
and text
for some number of stories, whose IDs are now known.
Imagine that at some future time, the variable $showComments
became true
. Relay will refetch only the data it needs using the node
root field.
query {
node(id: "ABC123") {
fragment on Story { comments(first: 10) { author, commentText } }
}
node(id: "DEF456") {
fragment on Story { comments(first: 10) { author, commentText } }
}
node(id: "GHI789") {
fragment on Story { comments(first: 10) { author, commentText } }
}
...
}
This depends on a few pieces:
- Each object must have a globally unique ID, or be identified by a type/ID pair (the
globalIdField
helper does this and produces a base64 encoded string). - The server must know how to resolve an object from a globally unique ID, and vice versa. This is what the
nodeDefinitions
are for. - Any object that hopes to be refetchable using this system must implement the
nodeInterface
.
See also: https://facebook.github.io/relay/docs/graphql-object-identification.html#content
来源:https://stackoverflow.com/questions/33399901/in-relay-what-role-do-the-node-interface-and-the-global-id-spec-play