GraphQL/Relay Schema 无法在“CreateLinkPayload”类型上查询字段“store”

Posted

技术标签:

【中文标题】GraphQL/Relay Schema 无法在“CreateLinkPayload”类型上查询字段“store”【英文标题】:GraphQL/Relay Schema Cannot query field "store" on type "CreateLinkPayload" 【发布时间】:2016-12-05 22:43:54 【问题描述】:

我可以使用 CURL 和 GraphiQL 工具成功地进行 graphql/relay 查询和突变:

但是,在我的 react/relay 应用程序中,我可以查询并将数据导入应用程序,但是 每次我尝试在我的应用程序中更改某些内容时,我都会在控制台中收到此错误:

    bundle.js:51511 Uncaught Error: GraphQL validation error ``Cannot query field "store" on type "CreateLinkPayload".`` in file 
`/Users/johndoe/react-relay-project/src/mutations/CreateLinkMutation.js`. Try updating your GraphQL schema if an argument/field/type was recently added.
(anonymous function) @ bundle.js:51511
getFatQuery @ bundle.js:51512
getFatQuery @ bundle.js:35664
getQuery @ bundle.js:35791
_handleCommit @ bundle.js:35539
commit @ bundle.js:35453
commit @ bundle.js:35894
(anonymous function) @ bundle.js:28526

每次我做npm start 我都会收到这个错误:

-- GraphQL Validation Error -- CreateLinkMutation --

File:  /Users/johndoe/react-relay-project/src/mutations/CreateLinkMutation.js
Error: Cannot query field "store" on type "CreateLinkPayload".
Source:
> 
>         store  linkConnection 
>         ^^^

CreateLinkMutation.js

import Relay from 'react-relay'

class CreateLinkMutation extends Relay.Mutation 
  getMutation() 
    return Relay.QL`
      mutation  createLink 
    `
  

  getVariables() 
    return 
      title: this.props.title,
      url: this.props.url
    
  

  getFatQuery() 
    return Relay.QL`
      fragment on CreateLinkPayload 
        linkEdge,
        store  linkConnection 
      
    `
  

  getConfigs() 
    return [
      type: 'RANGE_ADD',
      parentName: 'store',
      parentID: this.props.store.id,
      connectionName: 'linkConnection',
      edgeName: 'linkEdge',
      rangeBehaviors: 
        '': 'append'
      
    ]

  


export default CreateLinkMutation

Link.js的部分内容

Link = Relay.createContainer(Link, 
  fragments: 
    link: () => Relay.QL`
      fragment on Link 
        url,
        title
      
    `
  
)

App.js的部分内容

 handleSubmit(e) 
    e.preventDefault()
    Relay.Store.update(
      new CreateLinkMutation(
        title: this.refs.newTitle.value,
        url: this.refs.newUrl.value,
        store: this.props.store
      )
    )
    this.refs.newTitle.value = ''
    this.refs.newUrl.value = ''
  



App = Relay.createContainer(App, 
  initialVariables: 
    limit: 10
  ,
  fragments: 
    store: () => Relay.QL`
      fragment on Store 
        id,
        linkConnection(first: $limit) 
          edges 
            node 
              id,
              $Link.getFragment('link')
            
          
        
      
    `

  
)

main.js的部分内容

class LinkStoreRoute extends Relay.Route 
  static routeName = 'LinkStoreRoute'
  static queries = 
    store: () => Relay.QL`query  store `
  

我的schema.js

const store = 

const Store = new GraphQLObjectType(
  name: 'Store',
  fields: () => (
    id: globalIdField('Store'),
    linkConnection: 
      type: linkConnection.connectionType,
      args: connectionArgs,
      resolve: (_, args) => 
        return docClient.scan(
          Object.assign(
            ,
            TableName: linksTable,
            paginationToParams(args)
          )
        ).promise().then(dataToConnection)
      
    
  )
)

const Link = new GraphQLObjectType(
  name: 'Link',
  fields: () => (
    id: 
      type: new GraphQLNonNull(GraphQLID),
      resolve: (obj) => obj.id
    ,
    title:  type: GraphQLString ,
    url:  type: GraphQLString 
  )
)

const linkConnection = connectionDefinitions(
  name: 'Link',
  nodeType: Link
)

let createLinkMutation = mutationWithClientMutationId(

  name: 'CreateLink',

  inputFields: 
    title:  type: new GraphQLNonNull(GraphQLString) ,
    url:  type: new GraphQLNonNull(GraphQLString) 
  ,

  outputFields: 
    linkEdge: 
      type: linkConnection.edgeType,
      resolve: (obj) => (node: obj, cursor: obj.id)
    
  ,

  store: 
    type: Store,
    resolve: () => store
  ,

  mutateAndGetPayload: (inputFields) => 

    let link = 
      id: uuid.v4(),
      title: inputFields.title,
      url: inputFields.url
    

    return new Promise((resolve, reject) => 
      docClient.put(
        Object.assign(
          ,
          TableName: linksTable,
          Item: link
        ),
        (err, data) => 
          if (err) return reject(err)
          return resolve(link)
        
      )
    )
  
)

const schema = new GraphQLSchema(
  query: new GraphQLObjectType(
    name: 'Query',
    fields: () => (
      store: 
        type: Store,
        resolve: () => store
      
    )
  ),

  mutation: new GraphQLObjectType(
    name: 'Mutation',
    fields: () => (
      createLink: createLinkMutation
    )
  )
)

module.exports = schema

请注意,我在顶部排除了 40 行 require 语句。

这怎么可能?我该如何解决? 会不会是relay/react的bug?

【问题讨论】:

【参考方案1】:

CreateLinkMutation(CreateLinkMutation.js 文件)的客户端实现中,getFatQuery() 函数指定它在变异完成后需要两个输出 - linkEdgestore。因此,在您的变更的服务器端实现中,您必须将这两件事作为输出包括在内。但是,在您当前的实现中,只有 linkEdge 包含在突变的输出中(schema.js 文件中的createLinkMutation)。要解决此问题,请在输出中包含 store

outputFields: 
  linkEdge: 
    type: linkConnection.edgeType,
    resolve: (obj) => (node: obj, cursor: obj.id)
  ,
  store: 
    type: Store,
    resolve: () => store
  ,
,

【讨论】:

【参考方案2】:

原来是商店

  store: 
    type: Store,
    resolve: () => store
  

必须像这样进入 outputFields:

  outputFields: 
    linkEdge: 
      type: linkConnection.edgeType,
      resolve: (obj) => (node: obj, cursor: obj.id)
    
    store: 
      type: Store,
      resolve: () => store
    
  

【讨论】:

以上是关于GraphQL/Relay Schema 无法在“CreateLinkPayload”类型上查询字段“store”的主要内容,如果未能解决你的问题,请参考以下文章

Graphql + Relay graphql-relay-js 依赖

GraphQL 和 Relay 的概念

如何在 GraphQL (Relay) 中查询和改变数组类型?

GraphQL + Relay:如何执行重新获取授权?

GraphQL / Relay - 是不是需要在主 QueryRenderer 中查询所有表?

在 graphql/relay 中维护有序列表