GraphQL 突变和查询:无法读取未定义的属性

cli*_*qer 2 reactjs graphql express-graphql

我正在按照教程进行操作,并使用express-graphql. 我有一个突变来创建一个Friend对象和一个查询来返回相同的对象。自动完成和模式检测在 localhost:8080/graphql 上运行的 GraphiQL 上运行良好。我尝试在 SO 上搜索类似的错误,但这些错误要么有复杂的示例,要么正在使用 Apollo。

这是我尝试执行的 GraphQL 突变:

mutation {
  createFriend(input: {
    firstName:"FName1",
    lastName:"LName1",
    email:"test@test.com"
  }) {
    id
  }
}
Run Code Online (Sandbox Code Playgroud)

和我看到的错误(仅显示错误的相关部分):

{
  "errors": [
    {
      "message": "Cannot read property 'input' of undefined",
// Erased irrelevant portion of error
}
Run Code Online (Sandbox Code Playgroud)

这是我的 schema.js 文件,它导入resolversresolvers.js使用makeExecutableSchema

import { resolvers } from './resolvers';
import { makeExecutableSchema } from '@graphql-tools/schema';

const typeDefs = `
    type Friend {
        id: ID
        firstName: String
        lastName: String
        age: Int
        email: String
    }

    type Query {
        getFriend(id: ID): Friend
    }

    input FriendInput {
        id: ID
        firstName: String!
        lastName: String
        age: Int
        email: String
    }

    type Mutation {
        createFriend(input: FriendInput): Friend
    }
`;

export const schema = makeExecutableSchema({ typeDefs, resolvers});
Run Code Online (Sandbox Code Playgroud)

由于我只是在探索 graphQL 和 React,因此我一直将Friend对象保存在数组中,如我的resolver.js文件中所示:

class Friend {
    constructor(id, { firstName, lastName, gender, age, language, email, contacts }) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.gender = gender;
        this.age = age;
        this.language = language;
        this.email = email;
        this.contacts = contacts;
    }
}

const friendDatabase = {};

// resolver map
export const resolvers = {
    Query: {
        getFriend: ({ id }) => {
            return new Friend(id, friendDatabase[id]);
        },
    },
    Mutation: {
        createFriend: ({ input }) => {
            let id = require('crypto').randomBytes(10).toString('hex');
            friendDatabase[id] = input;
            return new Friend(id, input);
        },
    },
};
Run Code Online (Sandbox Code Playgroud)

最后,这是将所有内容连接在一起的 index.js 文件:

import express from 'express';
const { graphqlHTTP } = require('express-graphql');
import {schema} from './schema';

const app = express();

app.get('/', (req, res) => {
    res.send('GraphQL is amazing!');
});

app.use('/graphql', graphqlHTTP({
    schema: schema,
    graphiql: true,
}));

app.listen(8080, () => console.log('Running server on port localhost:8080/graphql'));
Run Code Online (Sandbox Code Playgroud)

我发现本教程使用了一些过时的库(graphql-tools 而不是 @graphql-tools/schema),npm 日志向我指出了这些库。我一直在更新代码,但无法调试此错误。

任何指示将不胜感激。

编辑 基于@Viet的评论,使用这个:

mutation {
  createFriend({
    firstName:"FName1",
    lastName:"LName1",
    email:"test@test.com"
  }) {
    id
  }
}
Run Code Online (Sandbox Code Playgroud)

我现在收到此错误:

{
  "errors": [
    {
      "message": "Syntax Error: Expected Name, found \"{\".",
// Removed extra lines
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

cli*_*qer 6

感谢@xadm 的评论,我让它工作了。查看此处的查询解析器文档,createFriend突变签名如下所示:

createFriend: (parent, {input}, context, info) => {//Do something}
Run Code Online (Sandbox Code Playgroud)

在我最初的帖子中,我只提供了这个:

createFriend: ({input}) => {//Do something}
Run Code Online (Sandbox Code Playgroud)

由于我对传递父参数并不真正感兴趣,所以我需要做的就是:

createFriend: (_, {input}) => {//Do something}
Run Code Online (Sandbox Code Playgroud)

进行上述更改无需编辑我的突变查询或任何其他文件。希望其他人觉得这很有用。

  • 同意,需要等待 24 小时才能接受我的答案 (2认同)