如何将视频节点从resolve / database传递到graphql relay中的节点定义?

时间:2017-01-24 00:37:26

标签: javascript graphql relayjs graphql-js

我的节点定义如下所示:

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
  }
)

问题是视频节点总是为空,即使从数据库返回实际视频,因为它不是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 relay理解的东西:

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

可能是问题。

此外,询问/查询id会使整个视频对象为空:

enter image description here

但是,从查询中省略id会返回一些内容,无论是否使用relay id查询:

enter image description here

或数据库ID

enter image description here

并查询所有视频的作品:

enter image description here

有趣的是,即使我从节点定义中删除视频部分,我也会遇到完全相同的问题:

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

为什么呢?我清楚地将它们定义在顶部!

另外,我可以这样做:

enter image description here

但这不起作用:

enter image description here

这是video: {} resolve:

中返回的内容
{ 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而言,null可以,但不是正常(最终videotoGlobalId

我是否需要将节点ID转换为全局ID?使用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: '' }

然而,如果我这样做

enter image description here

我得到了

{  
   "status":"success",
   "response":{  
      "token":"test_token",
      "expires":"1485217863"
   }
}

1 个答案:

答案 0 :(得分:0)

因此,为了使节点定义有效,我所要做的就是:

class Video {}
let video = new Video()
return Object.assign(video, data.Items[0])

即。创建与类型名称相同的类 然后Object.assign到它

这样做是行不通的:

return {Video: data.Items[0]}

我还需要在数据库中创建ID:Video:f4623d92-3b48-4e1a-bfcc-01ff3c8cf754,其中我基本上将type和随机生成的唯一ID一起用冒号(:)分隔,然后使用toGlobalId库的graphql-relay-js函数对其进行编码(因此我最终得到VmlkZW86ZjQ2MjNkOTItM2I0OC00ZTFhLWJmY2MtMDFmZjNjOGNmNzU0Og==),然后我可以使用fromGlobalId对其进行解码,以便node definitions可以检索typeid{ type: 'Video', id: 'f4623d92-3b48-4e1a-bfcc-01ff3c8cf754:' })之后,我仍然需要添加fromGlobalId(globalId).id.replace(/\:$/, ''))来删除尾部冒号(:)。 `

此外,interfaces并不意味着可以访问,它们仅用于配置。