如何将视频节点从 resolve/database 传递到 graphql 中继中的节点定义?
How to pass video node from resolve/database to node definitions in graphql relay?
我的节点定义如下所示:
class Store {}
let store = new Store()
let nodeDefs = nodeDefinitions(
(globalId) => {
let type = fromGlobalId(globalId).type
let id = fromGlobalId(globalId).id
if (type === 'Store') {
return store
}
if (type === 'Video') {
return docClient.query(
Object.assign(
{},
{TableName: videosTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': id }}
)
).promise().then(dataToConnection)
}
return null
},
(obj) => {
if (obj instanceof Store) {
return storeType
}
if (obj instanceof Video) {
return videoType
}
return null
}
)
问题是视频节点始终为空,即使从数据库返回实际视频也是如此,因为要使其不为空,我需要根据 ID 查找它或以某种方式从数据库中获取它。
这是我指的视频节点:
video: {
type: videoType,
args: Object.assign(
{},
connectionArgs,
{id: {type: GraphQLString}}
),
resolve: (_, args) => {
return docClient.query(
Object.assign(
{},
{TableName: pokemonTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': args.id }},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
},
和
const videoType = new GraphQLObjectType({
name: 'Video',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLID),
resolve: (obj) => obj.id
},
name: { type: GraphQLString },
url: { type: GraphQLString }
}),
interfaces: [nodeDefs.nodeInterface]
})
const allVideosConnection = connectionDefinitions({
name: 'Video',
nodeType: videoType
})
我尝试直接在节点定义内进行数据库查询,但那没有用。
dataToConnection
只是转换了dynamoDB的输出:
video DATA!! { Items:
[ { id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754',
url: 'http://www.pokkentournament.com/assets/img/characters/char-detail/detail-pikachuLibre.png',
name: 'YAHOO' } ],
Count: 1,
ScannedCount: 1 }
变成 graphql 中继可以理解的东西:
video dataToConnection!! { edges:
[ { cursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
node: [Object] } ],
pageInfo:
{ startCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
endCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
hasPreviousPage: false,
hasNextPage: false } }
函数本身可以在这里找到:https://github.com/dowjones/graphql-dynamodb-connections/pull/3/files
可能是问题所在。
此外,asking/querying for id 使整个视频对象为空:
但是从查询中省略了id returns 东西,是否用relay id查询:
或数据库ID
并查询所有视频有效:
有趣的是,即使我从节点定义中删除视频部分,我也会遇到完全相同的问题:
let nodeDefs = nodeDefinitions(
(globalId) => {
let type = fromGlobalId(globalId).type
let id = fromGlobalId(globalId).id
if (type === 'Store') {
return store
}
return null
},
(obj) => {
if (obj instanceof Store) {
return storeType
}
return null
}
)
有什么想法吗?
更新:
我做了一些挖掘,发现接口实际上是 undefined
const storeType = new GraphQLObjectType({
name: 'Store',
fields: () => ({
id: globalIdField('Store'),
allVideosConnection: {
type: allVideosConnection.connectionType,
args: Object.assign(
{},
connectionArgs
),
resolve: (_, args) => {
return docClient.scan(
Object.assign(
{},
{TableName: pokemonTable},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
},
video: {
type: videoType,
args: Object.assign(
{},
connectionArgs,
{id: {type: GraphQLString}}
),
resolve: (_, args) => {
return docClient.query(
Object.assign(
{},
{TableName: pokemonTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': args.id }},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
}
}),
interfaces: [nodeDefs.nodeInterface]
})
console.dir(storeType.interfaces, { depth: null })
打印undefined
为什么?我在顶部明确定义了它们!
此外,我可以做到:
但这行不通:
这是 video: {}
解析中返回的内容:
{ edges:
[ { cursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
node:
{ id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754',
url: 'http://www.pokkentournament.com/assets/img/characters/char-detail/detail-pikachuLibre.png',
name: 'YAHOO' } } ],
pageInfo:
{ startCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
endCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
hasPreviousPage: false,
hasNextPage: false } }
allVideosConnection
还可以,但 video
不行(最终 null
)
我是否需要将节点的 ID 转换为全局 ID?使用 toGlobalId
?只为 video
?
因为我注意到的另一件事是如果我
console.log('fromGlobalId', fromGlobalId(globalId))
在我的节点定义中,这个查询:
{
node(id: "f4623d92-3b48-4e1a-bfcc-01ff3c8cf754") {
id
...F1
}
}
fragment F1 on Video {
url
name
}
变成这样:
fromGlobalId { type: '', id: '\u000e6]_v{vxsn\u001eU/\u001b}G>SW_]O\u001c>x' }
但是,如果我这样做
我明白了
globalId U3RvcmU6
fromGlobalId { type: 'Store', id: '' }
所以要使节点定义起作用,我所要做的就是:
class Video {}
let video = new Video()
return Object.assign(video, data.Items[0])
即创建与类型名称同名的 class
然后Object.assign到它
仅仅这样做是行不通的:
return {Video: data.Items[0]}
我还需要像这样在数据库中创建 ID:Video:f4623d92-3b48-4e1a-bfcc-01ff3c8cf754
,我实际上是将 type
和随机生成的唯一 ID 放在一起,用冒号分隔 (:
)然后使用 graphql-relay-js
库的 toGlobalId
函数对其进行编码(所以我最终得到 VmlkZW86ZjQ2MjNkOTItM2I0OC00ZTFhLWJmY2MtMDFmZjNjOGNmNzU0Og==
),然后我可以使用 fromGlobalId
对其进行解码,以便 node definitions
可以检索 type
和 id
({ type: 'Video', id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754:' }
),之后我仍然需要添加 fromGlobalId(globalId).id.replace(/\:$/, ''))
以删除结尾的冒号 (:
)。
`
此外,interfaces
并不意味着可访问,它们仅用于配置。
我的节点定义如下所示:
class Store {}
let store = new Store()
let nodeDefs = nodeDefinitions(
(globalId) => {
let type = fromGlobalId(globalId).type
let id = fromGlobalId(globalId).id
if (type === 'Store') {
return store
}
if (type === 'Video') {
return docClient.query(
Object.assign(
{},
{TableName: videosTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': id }}
)
).promise().then(dataToConnection)
}
return null
},
(obj) => {
if (obj instanceof Store) {
return storeType
}
if (obj instanceof Video) {
return videoType
}
return null
}
)
问题是视频节点始终为空,即使从数据库返回实际视频也是如此,因为要使其不为空,我需要根据 ID 查找它或以某种方式从数据库中获取它。
这是我指的视频节点:
video: {
type: videoType,
args: Object.assign(
{},
connectionArgs,
{id: {type: GraphQLString}}
),
resolve: (_, args) => {
return docClient.query(
Object.assign(
{},
{TableName: pokemonTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': args.id }},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
},
和
const videoType = new GraphQLObjectType({
name: 'Video',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLID),
resolve: (obj) => obj.id
},
name: { type: GraphQLString },
url: { type: GraphQLString }
}),
interfaces: [nodeDefs.nodeInterface]
})
const allVideosConnection = connectionDefinitions({
name: 'Video',
nodeType: videoType
})
我尝试直接在节点定义内进行数据库查询,但那没有用。
dataToConnection
只是转换了dynamoDB的输出:
video DATA!! { Items:
[ { id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754',
url: 'http://www.pokkentournament.com/assets/img/characters/char-detail/detail-pikachuLibre.png',
name: 'YAHOO' } ],
Count: 1,
ScannedCount: 1 }
变成 graphql 中继可以理解的东西:
video dataToConnection!! { edges:
[ { cursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
node: [Object] } ],
pageInfo:
{ startCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
endCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
hasPreviousPage: false,
hasNextPage: false } }
函数本身可以在这里找到:https://github.com/dowjones/graphql-dynamodb-connections/pull/3/files
可能是问题所在。
此外,asking/querying for id 使整个视频对象为空:
但是从查询中省略了id returns 东西,是否用relay id查询:
或数据库ID
并查询所有视频有效:
有趣的是,即使我从节点定义中删除视频部分,我也会遇到完全相同的问题:
let nodeDefs = nodeDefinitions(
(globalId) => {
let type = fromGlobalId(globalId).type
let id = fromGlobalId(globalId).id
if (type === 'Store') {
return store
}
return null
},
(obj) => {
if (obj instanceof Store) {
return storeType
}
return null
}
)
有什么想法吗?
更新:
我做了一些挖掘,发现接口实际上是 undefined
const storeType = new GraphQLObjectType({
name: 'Store',
fields: () => ({
id: globalIdField('Store'),
allVideosConnection: {
type: allVideosConnection.connectionType,
args: Object.assign(
{},
connectionArgs
),
resolve: (_, args) => {
return docClient.scan(
Object.assign(
{},
{TableName: pokemonTable},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
},
video: {
type: videoType,
args: Object.assign(
{},
connectionArgs,
{id: {type: GraphQLString}}
),
resolve: (_, args) => {
return docClient.query(
Object.assign(
{},
{TableName: pokemonTable},
{KeyConditionExpression: 'id = :id'},
{ExpressionAttributeValues: { ':id': args.id }},
paginationToParams(args)
)
).promise().then(dataToConnection)
}
}
}),
interfaces: [nodeDefs.nodeInterface]
})
console.dir(storeType.interfaces, { depth: null })
打印undefined
为什么?我在顶部明确定义了它们!
此外,我可以做到:
但这行不通:
这是 video: {}
解析中返回的内容:
{ edges:
[ { cursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
node:
{ id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754',
url: 'http://www.pokkentournament.com/assets/img/characters/char-detail/detail-pikachuLibre.png',
name: 'YAHOO' } } ],
pageInfo:
{ startCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
endCursor: 'ZHluYW1vZGJjb25uZWN0aW9uOmY0NjIzZDkyLTNiNDgtNGUxYS1iZmNjLTAxZmYzYzhjZjc1NA==',
hasPreviousPage: false,
hasNextPage: false } }
allVideosConnection
还可以,但 video
null
)
我是否需要将节点的 ID 转换为全局 ID?使用 toGlobalId
?只为 video
?
因为我注意到的另一件事是如果我
console.log('fromGlobalId', fromGlobalId(globalId))
在我的节点定义中,这个查询:
{
node(id: "f4623d92-3b48-4e1a-bfcc-01ff3c8cf754") {
id
...F1
}
}
fragment F1 on Video {
url
name
}
变成这样:
fromGlobalId { type: '', id: '\u000e6]_v{vxsn\u001eU/\u001b}G>SW_]O\u001c>x' }
但是,如果我这样做
我明白了
globalId U3RvcmU6
fromGlobalId { type: 'Store', id: '' }
所以要使节点定义起作用,我所要做的就是:
class Video {}
let video = new Video()
return Object.assign(video, data.Items[0])
即创建与类型名称同名的 class 然后Object.assign到它
仅仅这样做是行不通的:
return {Video: data.Items[0]}
我还需要像这样在数据库中创建 ID:Video:f4623d92-3b48-4e1a-bfcc-01ff3c8cf754
,我实际上是将 type
和随机生成的唯一 ID 放在一起,用冒号分隔 (:
)然后使用 graphql-relay-js
库的 toGlobalId
函数对其进行编码(所以我最终得到 VmlkZW86ZjQ2MjNkOTItM2I0OC00ZTFhLWJmY2MtMDFmZjNjOGNmNzU0Og==
),然后我可以使用 fromGlobalId
对其进行解码,以便 node definitions
可以检索 type
和 id
({ type: 'Video', id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754:' }
),之后我仍然需要添加 fromGlobalId(globalId).id.replace(/\:$/, ''))
以删除结尾的冒号 (:
)。
`
此外,interfaces
并不意味着可访问,它们仅用于配置。