0

I tried to connect schemas and resolvers using graphql-tools. To do this, I moved them into separate folders, and used the mergeSchemas and mergeResolvers functions. I need to do this because there will be many models, the files will be large, and there will be confusion. After I moved the files to folders and started using graphql-tools, there were errors. Please tell me how to merge correctly. Below is the code of the schema and resolvers (I removed some of the fields, since they worked fine before, the problem appeared after trying to use graphql-tools).

Schema code (I am using ES6 syntax):

import { buildSchema } from 'graphql';

export default buildSchema(`
type User {
  _id: ID!
  name: String!
  email: String!
  password: String!
  avatar: String
  date: String
}
type Auth {
  token: String!
}
input UserInput {
  name: String!
  email: String!
  password: String!
  date: String
  token: String!
}
input UserUpdate {
  _id: ID!
  name: String!
  email: String!
  password: String!
  token: String!
} 
input UserRemove {
  _id: ID!
  token: String!
}
input UserAuth {
  email: String!
  password: String!
} 
type RootQuery {
  users: [User!]!
  findUser(id: ID!): User
}
type RootMutation {
  createUser(userInput: UserInput): User
  deleteUser(userRemove: UserRemove): User
  updateUser(userUpdate: UserUpdate): User
  authUser(userAuth: UserAuth): Auth
}
schema {
  query: RootQuery
  mutation: RootMutation
}
`);

index.js (in schema folder):

import { mergeSchemas } from 'graphql-tools';
import user from './user';

export default schema = mergeSchemas({
  schemas: [
    user
  ]
});

Resolver code:

import User from '../models/User';

export default {
  users: () => {
    return User.find().select('-password')
      .then(users => {
        return users.map(user => {
          return {
            ...user._doc,
            _id: user.id,
            date: new Date(user.date).toISOString()
          };
        });
      })
      .catch(err => {
        throw err;
      });
  },
  findUser: async (args) => {
    try {
      let user = await User.findById(args.id).select('-password');
      return {
        ...user._doc,
        date: new Date(user.date).toISOString()
      };
    } catch (err) {
      console.log(err);
      throw err;
    }
  },
  createUser: async args => {
    const { name, email, password, token } = args.userInput;
    try {
      // Check if user exists:
      let user = await User.findOne({ email });
      if (user) {
        return new Error('User already exists');
      }
      // Get users gravatar:
      const avatar = gravatar.url(email, {
        s: '200',
        r: 'pg',
        d: 'mm'
      });
      user = new User({
        name,
        email,
        password,
        avatar,
        date: new Date(args.userInput.date)
      });
      // Encrypt password:
      const salt = await bcrypt.genSalt(10);
      user.password = await bcrypt.hash(password, salt);
      await user.save();
      return {
        _id: user._id,
        name: user.name,
        email: user.email,
        avatar: user.avatar,
        date: new Date(user.date).toISOString()
      }
    } catch (err) {
      throw err;
    }
  },
  deleteUser: async (args) => {
    const { _id, token } = args.userRemove;
    try {
      const user = await User.findById(_id);
      return user.remove().then(result => {
        return { ...result._doc, _id: result._doc._id.toString() };
      });
    } catch (err) {
      throw err;
    }
  },
  updateUser: async (args) => {
    const { _id, name, email, password, token } = args.userUpdate;
    try {
      // Get users gravatar:
      const avatar = gravatar.url(email, {
        s: '200',
        r: 'pg',
        d: 'mm'
      });
      const user = await User.findById(_id);
      user.name = name;
      user.email = email;
      // Encrypt password:
      const salt = await bcrypt.genSalt(10);
      user.password = await bcrypt.hash(password, salt);
      user.avatar = avatar;
      await user.save();
      return user;
    } catch (err) {
      console.log(err);
      throw err;
    }
  },
  authUser: async (args) => {
    const { email, password } = args.userAuth;
    try {
      // Check if user exists:
      let user = await User.findOne({ email });
      if (!user) {
        return new Error('Invalid Credentials');
      }
      // Compare password
      const isMatch = await bcrypt.compare(password, user.password);
      if (!isMatch) {
        return new Error('Invalid Credentials');
      }
      // JWT Token:
      const payload = {
        user: {
          id: user._id
        }
      };
      let token = await jwt.sign(
        payload,
        process.env.JWT_SECRET,
        { expiresIn: 360000 },   // Expiration (optional)
      );
      return {
        token: token
      }
    } catch (err) {
      throw err;
    }
  }
};

index.js (in resolvers folder):

import { mergeResolvers } from 'graphql-tools';
import user from './user';

export default resolvers = mergeResolvers({
  resolvers: [
    user
  ]
});

server.js (starter):

import express from 'express';
import cors from 'cors';
import connectDB from './db';
import { graphqlHTTP } from 'express-graphql';

import schema from './schema';
import resolvers from './resolvers';

const app = express();

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

app.use(cors());

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

app.get('/', (req, res) => {
  res.send('12345');
});

connectDB();
app.listen(5000, _ => console.log('Server started at 5000...'));

Files and folders structure:

schema
  |__ index.js
  |__ user.js (schema)
resolvers
  |__ index.js
  |__ user.js (resolver)
server.js

Thanks for attention.

Kiten
  • 985
  • 2
  • 17
  • 35

0 Answers0