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

时间:2016-07-31 22:31:22

标签: javascript reactjs graphql relayjs

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

enter image description here

然而,在我的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语句。

这怎么可能?我该如何解决? 这可能是继电器/反应的错误吗?

2 个答案:

答案 0 :(得分:7)

CreateLinkMutation(CreateLinkMutation.js文件)的客户端实现中,getFatQuery()函数指定在变异完成后它需要两个输出 - linkEdge和{{1} }。因此,在服务器端实现变异时,必须将这两项内容作为输出。但是,当前实现中的变异输出中仅包含store(schema.js文件中为linkEdge)。要解决此问题,请在输出中包含createLinkMutation

store

答案 1 :(得分:1)

结果商店

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

必须像这样进入outputFields:

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