简体   繁体   中英

Getting error in Express GraphQL: Schema must contain uniquely named types but contains multiple types named "String"

So I was trying to create a Pinterest Clone using GraphQL and I am stuck with this error.

Project Structure looks something like this

vscode项目结构

There are 2 models, User and Pins

Pin Model

const mongoose = require('mongoose');

const pinSchema = new mongoose.Schema({
  title: {
    type: String,
    required: [true, 'Title is Required'],
    unique: [true, 'Title should be unique'],
  },
  imageUrl: {
    type: String,
    required: [true, 'Image URL is Required'],
  },
  description: {
    type: String,
  },
  link: {
    type: String,
  },
  userId: {
    type: mongoose.Schema.Types.ObjectId, // to store which user
    required: true,
  },
  createdAt: {
    type: Date,
    default: Date.now(),
  },
});

const Pin = mongoose.model('Pin', pinSchema);
module.exports = Pin;

User Model

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: [true, 'Name is Required'],
  },
  userName: {
    type: String,
    required: [true, 'Username is Required'],
    unique: [true, 'Username should be unique'],
  },
  email: {
    type: String,
    required: [true, 'Email is Required'],
    unique: [true, 'Email should be unique'],
  },
  password: {
    type: String,
    required: [true, 'Password is Required'],
  },
  createdPins: {
    type: [mongoose.Schema.Types.ObjectId], // store all pins created by this user
  },
  savedPins: {
    type: [mongoose.Schema.Types.ObjectId], // store all pins saved by this user
  },
});

const User = mongoose.model('User', userSchema);
module.exports = User;

Graphql PinType

const { GraphQLObjectType, GraphQLID, GraphQLString } = require('graphql');
const User = require('../models/UserModel');

const PinType = new GraphQLObjectType({
  name: 'Pin',
  fields: () => ({
    id: { type: GraphQLID },
    title: { type: GraphQLString },
    imageUrl: { type: GraphQLString },
    description: { type: GraphQLString },
    link: { type: GraphQLString },
    user: {
      type: UserType,
      resolve(parent, args) {
        return User.findById(parent.userId);
      },
    },
    createdAt: { type: String },
  }),
});

module.exports = PinType;

const UserType = require('./UserSchema');

Graphql UserType

const {
  GraphQLObjectType,
  GraphQLID,
  GraphQLString,
  GraphQLList,
} = require('graphql');

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
      id: { type: GraphQLID },
      name: { type: GraphQLString },
      userName: { type: GraphQLString },
      createdPins: { type: new GraphQLList(PinType) },
      savedPins: { type: new GraphQLList(PinType) },
  }),
});

module.exports = UserType;

const PinType = require('./PinSchema');

Query and Mutation: schema.js file

const {
  GraphQLObjectType,
  GraphQLList,
  GraphQLID,
  GraphQLSchema,
  GraphQLNonNull,
  GraphQLString,
} = require('graphql');

const User = require('../models/UserModel');
const Pin = require('../models/PinModel');

const UserType = require('./UserSchema');
const PinType = require('./PinSchema');

// Query
const RootQuery = new GraphQLObjectType({
  name: 'RootQuery',
  fields: {
    // Get all Users
    users: {
      type: new GraphQLList(UserType),
      resolve(parent, args) {
        return User.find();
      },
    },
    // Get a Single User
    user: {
      type: UserType,
      args: { id: { type: GraphQLID } },
      resolve(parent, args) {
        return User.findById(args.id);
      },
    },
    // Get all Pins
    pins: {
      type: new GraphQLList(PinType),
      resolve(parent, args) {
        return Pin.find();
      },
    },
    // Get a Single Pin
    pin: {
      type: PinType,
      args: { id: { type: GraphQLID } },
      resolve(parent, args) {
        return Pin.findById(args.id);
      },
    },
  },
});

// Mutation
const Mutation = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    // Create User
    createUser: {
      type: UserType,
      args: {
        name: { type: new GraphQLNonNull(GraphQLString) },
        userName: { type: new GraphQLNonNull(GraphQLString) },
        email: { type: new GraphQLNonNull(GraphQLString) },
        password: { type: new GraphQLNonNull(GraphQLString) },
      },
      resolve(parent, args) {
        return User.create({
          name: args.name,
          userName: args.userName,
          email: args.email,
          password: args.password,
        });
      },
    },
    // Delete User
    deleteUser: {
      type: UserType,
      args: {
        id: { type: new GraphQLNonNull(GraphQLID) },
      },
      resolve(parent, args) {
        // delete all pins created by this user
        Pin.find({ userId: args.id }).then((pins) => {
          pins.forEach((pin) => {
            pin.remove();
          });
        });
        return User.findByIdAndRemove(args.id);
      },
    },
    // Create a Pin
    createPin: {
      type: PinType,
      args: {
        title: { type: new GraphQLNonNull(GraphQLString) },
        imageUrl: { type: new GraphQLNonNull(GraphQLString) },
        description: { type: GraphQLString },
        link: { type: GraphQLString },
        userId: { type: new GraphQLNonNull(GraphQLID) },
      },
      resolve(parent, args) {
        return Pin.create({
          title: args.title,
          imageUrl: args.imageUrl,
          description: args.description,
          link: args.link,
          userId: args.userId,
        });
      },
    },
    // Update a Pin
    updatePin: {
      type: PinType,
      args: {
        id: { type: new GraphQLNonNull(GraphQLID) },
        title: { type: GraphQLString },
        imageUrl: { type: GraphQLString },
        description: { type: GraphQLString },
        link: { type: GraphQLString },
      },
      resolve(parent, args) {
        return Pin.findByIdAndUpdate(
          args.id,
          {
            $set: {
              title: args.title,
              imageUrl: args.imageUrl,
              description: args.description,
              link: args.link,
            },
          },
          { new: true }
        );
      },
    },
    // Delete a Pin
    deletePin: {
      type: PinType,
      args: {
        id: { type: new GraphQLNonNull(GraphQLID) },
      },
      resolve(parent, args) {
        // remove this pin from the createdPins of the user
        User.updateMany(
          {},
          {
            $pullAll: {
              createdPins: [args.id],
            },
          }
        );
        // delete this pin
        return Pin.findByIdAndRemove(args.id);
      },
    },
  },
});

const schema = new GraphQLSchema({
  query: RootQuery,
  mutation: Mutation,
});

module.exports = schema;

Getting this error

Error: Schema must contain uniquely named types but contains multiple types named "String". at new GraphQLSchema (D:\Projects\Pinterest Clone\server\node_modules\graphql\type\schema.js:219:15) at Object.<anonymous> (D:\Projects\Pinterest Clone\server\schemas\schema.js:159:16) at Module._compile (node:internal/modules/cjs/loader:1149:14) at Module._extensions..js (node:internal/modules/cjs/loader:1203:10) at Module.load (node:internal/modules/cjs/loader:1027:32) at Module._load (node:internal/modules/cjs/loader:868:12) at Module.require (node:internal/modules/cjs/loader:1051:19) at require (node:internal/modules/cjs/helpers:103:18) at Object.<anonymous> (D:\Projects\Pinterest Clone\server\index.js:6:16) at Module._compile (node:internal/modules/cjs/loader:1149:14)

Node.js v18.10.0

Tried to search for this and found many people faced similar kind of issues, but I couldn't solve it.

Found the Bug. It was in the Graphql PinType file. While defining the schema, I used "String" instead of "GraphqlString" in the field "createdAt" which was causing the error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM