我尝试使用graphql-tools连接模式和解析器。为此,我将它们移动到单独的文件夹中,并使用了mergeSchemas和mergeResolvers函数。我需要这样做,因为会有很多模型,文件会很大,并且会出现混乱。在我将文件移动到文件夹并开始使用 graphql-tools 后,出现了错误。请告诉我如何正确合并。下面是模式和解析器的代码(我删除了一些字段,因为它们之前运行良好,尝试使用 graphql-tools 后出现问题)。
架构代码(我使用的是 ES6 语法):
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(在架构文件夹中):
import { mergeSchemas } from 'graphql-tools';
import user from './user';
export default schema = mergeSchemas({
schemas: [
user
]
});
解析器代码:
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(在解析器文件夹中):
import { mergeResolvers } from 'graphql-tools';
import user from './user';
export default resolvers = mergeResolvers({
resolvers: [
user
]
});
server.js(启动器):
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...'));
文件和文件夹结构:
schema
|__ index.js
|__ user.js (schema)
resolvers
|__ index.js
|__ user.js (resolver)
server.js
感谢关注。