【问题标题】:GraphQL Apollo Server: "Cannot return null for non-nullable field Mutation.createUser"GraphQL Apollo 服务器:“不能为不可为空的字段 Mutation.createUser 返回 null”
【发布时间】:2021-08-18 02:45:24
【问题描述】:

这可能已经被报告了 100 次,但仍在发布,因为这是最简单的情况,我无法弄清楚这里出了什么问题。

schema.js:

const { gql } = require("apollo-server");

const typeDefs = gql`
  scalar MongoID

  type User {
    _id: MongoID!
    address: String!
  }

  input LoginInput {
    address: String!
  }

  type Query {
    getUserById(userId: MongoID!): User!
  }

  type Mutation {
    createUser(loginInput: LoginInput): User!
  }
`;

module.exports = typeDefs;

解析器:

const User = require("../../models/User");

const createUser = async (args) => {
  try {
    const existingUser = await User.findOne({
      address: args.loginInput.address,
    });

    if (existingUser) {
      throw new Error("User already exists!");
    }

    const user = new User({
      address: args.loginInput.address,
    });

    const result = await user.save();

    return result;
  } catch (err) {
    console.error(err.message);
    res.status(500).send("Server error");
  }
};

module.exports = { createUser };

用户模型:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const UserSchema = new Schema({
  address: {
    type: String,
    unique: true,
    required: true,
  },
  date: {
    type: Date,
    default: Date.now,
  },
});

module.exports = User = mongoose.model("User", UserSchema);

变异:

mutation createUser($loginInput: LoginInput!) {
  createUser(loginInput: $loginInput) {
    _id
    address
  }
}

查询变量:

{
  "loginInput": {
    "address": "some address"
  }
}

此模式的所有查询和突变都会返回上述错误,因为我明确指定了User!。 注意:ID! 也会发生同样的事情,而不是 MongoId

这里有什么问题?

UPD:添加了server.js,因为没有处理任何查询(总是返回data:null),我认为设置可能有问题,尽管对此表示怀疑。

const express = require("express");
const session = require("express-session");
const { ApolloServer } = require("apollo-server-express");
const typeDefs = require("./graphql/schema/schema");
const rootResolver = require("./graphql/resolvers/index");
const config = require("config");
const sessionSecret = config.get("express_session_secret");
const connectDB = require("./config/db");

const app = express();

app.use(
  session({
    resave: true,
    saveUninitialized: true,
    secret: sessionSecret,
    cookie: {
      maxAge: 1000 * 60 * 60 * 24 * 355,
    },
  })
);

// Init Middleware
app.use(express.json({ extended: false }));

// Connect Database
connectDB();

const apolloServer = new ApolloServer({
  typeDefs,
  rootResolver,
});

apolloServer.applyMiddleware({ app });

// Serve static assets in production
if (process.env.NODE_ENV === "production") {
  // Set static folder
  app.use(express.static("client/build"));

  app.get("*", (req, res) => {
    res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
  });
}

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`);
  console.log(`GraphQL available at ${PORT}${apolloServer.graphqlPath}`);
});

运行时,成功获取控制台消息。

【问题讨论】:

    标签: graphql apollo-server


    【解决方案1】:

    就我而言,问题在于结构。当我使用apollo-server-express 时,我需要定义一个解析器文件(我之前合并了几个)。我用以下方式定义了resolvers.js,一切正常:

    const User = require("../../models/User");
    
    const resolvers = {
      Query: {
        getUserById(parent, args) {
          const user = User.findById(args.userId);
          return user;
        },
      },
    
      Mutation: {
        createUser(parent, args) {
          const existingUser = User.findOne({
            address: args.loginInput.address,
          });
    
          if (existingUser) {
            throw new Error("User already exists!");
          }
    
          const user = new User({
            address: args.loginInput.address,
          });
    
          const result = user.save();
    
          return {
            userId: user.id,
            address: user.address,
          };
        },
      },
    };
    
    module.exports = resolvers;
    

    注意:这是需要在构造函数中导入的,不要重命名文件:

    const apolloServer = new ApolloServer({
      typeDefs,
      resolvers,
    });
    

    【讨论】:

      猜你喜欢
      • 2019-10-25
      • 2020-10-27
      • 2021-10-07
      • 2018-01-28
      • 2019-07-08
      • 2019-05-28
      • 2018-04-10
      • 2023-03-28
      • 2021-11-27
      相关资源
      最近更新 更多