在中继中,节点接口和全局ID规范起什么作用? [英] In Relay, what role do the node interface and the global ID spec play?
问题描述
我从relay-starter-kit
开始,还通过Relay和GraphQL文档进行工作.但是,有很多地方是无法解释和神秘的.
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;
}
}
);
这有什么实际效果?
interfaces: [nodeInterface],
与此相关的是,此处的node
字段的作用是什么
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(),
},
}),
});
id
字段的神奇之处是什么? globalIdField
是做什么用的?
And what is the magic around the id
field? What is globalIdField
for?
我的数据库中有一个id
,并认为我可以在我的GraphQL对象中使用它:
I have an id
in my database and thought I could use it in my GraphQL objects:
代替:
id: globalIdField('User'),
我要使用我的数据库ID:
I want to use my database id:
id: {
type: GraphQLID,
description: 'The identifier'
},
但是,如果我这样做,我会在浏览器中看到一个错误,提示RelayQueryWriter: Could not find a type name for record '1'
.
But if I do that I get an error in the browser saying RelayQueryWriter: Could not find a type name for record '1'
.
我可以通过在组件容器的中继查询"中添加__typename
来消除该错误,但这似乎是错误的.
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.
谢谢
推荐答案
当Relay需要 refetch 一个对象时,Node
根字段与全局唯一ID一起起作用.当您调用this.props.relay.forceFetch()
或将查询的字段添加到由于全局ID已被部分提取而已知全局ID的对象时,就会发生重新引用.
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.
在这种情况下,Relay将缩短常规查询并直接使用其全局ID和node
根调用对对象执行查询.
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.
示例:
假定第一次解决此查询时$showComments
是false
.
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,
}
}
}
}
}
这将导致某些故事的id
和text
的获取,这些故事的ID现在已知.
This will have caused a fetch for id
and text
for some number of stories, whose IDs are now known.
想象在将来的某个时间,变量$showComments
变为true
.中继将使用node
根字段仅重新获取所需的数据.
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 } }
}
...
}
这取决于几块:
- 每个对象必须具有全局唯一的ID,或由一个类型/ID对标识(
globalIdField
助手会这样做,并生成base64编码的字符串). - 服务器必须知道如何从全局唯一ID解析对象,反之亦然.这就是
nodeDefinitions
的用途. - 任何希望使用此系统可重新获取的对象都必须实现
nodeInterface
.
- 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
.
另请参见: https://facebook.github.io/relay/docs/graphql-object-identification.html#content
这篇关于在中继中,节点接口和全局ID规范起什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!