【发布时间】:2020-04-21 13:37:38
【问题描述】:
我正在尝试创建一个自定义解析器来为使用 composeWithMongoose 的 Express + Apollo Server + Mongoose 项目上传用户头像图像。
正在使用 SchemaComposer 创建用户解析器,它从 Mongoose 架构生成它们,例如:
用户模型
import mongoose, { Schema } from 'mongoose';
import timestamps from 'mongoose-timestamp';
import bcrypt from 'mongoose-bcrypt';
import { composeWithMongoose } from 'graphql-compose-mongoose';
export const UserSchema = new Schema(
{
name: {
type: String,
trim: true,
required: true,
},
email: {
type: String,
lowercase: true,
trim: true,
unique: true,
},
phone: {
type: Number,
trim: true,
unique: true,
},
password: {
type: String,
bcrypt: true,
},
type: {
type: String,
},
image: {
type: String,
trim: true,
lowercase: true,
},
},
{
collection: 'users',
}
);
UserSchema.plugin(timestamps);
UserSchema.plugin(bcrypt);
UserSchema.index({ createdAt: 1, updatedAt: 1 });
export const User = mongoose.model('User', UserSchema);
export const UserTC = composeWithMongoose(User);
用户架构
import { User, UserTC } from '../models/user';
const UserQuery = {
userById: UserTC.getResolver('findById'),
userByIds: UserTC.getResolver('findByIds'),
userOne: UserTC.getResolver('findOne'),
userMany: UserTC.getResolver('findMany'),
userCount: UserTC.getResolver('count'),
userConnection: UserTC.getResolver('connection'),
userPagination: UserTC.getResolver('pagination'),
};
const UserMutation = {
userCreateOne: UserTC.getResolver('createOne'),
userCreateMany: UserTC.getResolver('createMany'),
userUpdateById: UserTC.getResolver('updateById'),
userUpdateOne: UserTC.getResolver('updateOne'),
userUpdateMany: UserTC.getResolver('updateMany'),
userRemoveById: UserTC.getResolver('removeById'),
userRemoveOne: UserTC.getResolver('removeOne'),
userRemoveMany: UserTC.getResolver('removeMany'),
};
export { UserQuery, UserMutation };
根据graphql-compose-mongoose documentation 和我的理解,我必须使用addResolver() 方法将解析器添加到ObjectTypeComposer (UserTC),例如:
用户架构
import { User, UserTC } from '../models/user';
import { GraphQLUpload } from 'graphql-upload';
UserTC.addResolver({
name: 'uploadImage',
type: 'String',
args: { userId: 'MongoID!', image: 'Upload!' },
resolve: async ({ source, args, context, info }) => {
const user = await User.findById({ _id: args.userId }).exec();
console.log(user);
}
});
const UserQuery = {
...
};
const UserMutation = {
...
uploadImage: UserTC.getResolver('uploadImage'),
};
export { UserQuery, UserMutation };
这一直有效,直到我将 image 参数类型从 String 更改为 Upload。其中,根据Apollo documentation默认开启。
我在控制台中收到此错误:Error: Type with name "Upload" does not exists。
但在这种情况下,我不确定如何使用 composeWithMongoose() 添加到我自己的类型定义中。
我很想听听其他方法 - 也许使用完全不同的方法是完全有效的。
编辑 1:回应@Daniel Rearden
我仍然收到Upload 类型不存在:
throw new Error(`Type with name ${(0, _misc.inspect)(typeName)} does not exists`); ^错误:名称为“上传”的类型不存在
- 我已安装:
express-graphql和apollo-upload-server。 - 我将中间件添加到服务器配置中:
import dotenv from 'dotenv';
import express from 'express';
import { ApolloServer } from 'apollo-server-express';
import mongoose from 'mongoose';
import bodyParser from 'body-parser';
import { apolloUploadExpress } from 'apollo-upload-server';
import './utils/db';
import schema from './schema';
dotenv.config();
const app = express();
app.use(
bodyParser.json(),
apolloUploadExpress()
);
const server = new ApolloServer({
schema,
cors: true,
playground: process.env.NODE_ENV === 'development' ? true : false,
introspection: true,
tracing: true,
path: '/',
});
...
- 我在 Schema 索引中提供了以下代码:
import { SchemaComposer } from 'graphql-compose';
import { GraphQLUpload } from 'apollo-upload-server';
import db from '../utils/db'; //eslint-disable-line no-unused-vars
const schemaComposer = new SchemaComposer();
schemaComposer.add(GraphQLUpload);
...
我仍然收到错误消息:Error: Type with name "Upload" does not exists。
编辑 2:另外,作为对@Daniel Rearden 的回应
好吧,我刚刚将自定义解析器添加到 UserMutation 架构中并且它起作用了:
const UserMutation = {
userCreateOne: UserTC.getResolver('createOne'),
userCreateMany: UserTC.getResolver('createMany'),
userUpdateById: UserTC.getResolver('updateById'),
userUpdateOne: UserTC.getResolver('updateOne'),
userUpdateMany: UserTC.getResolver('updateMany'),
userRemoveById: UserTC.getResolver('removeById'),
userRemoveOne: UserTC.getResolver('removeOne'),
userRemoveMany: UserTC.getResolver('removeMany'),
uploadImage: {
type: 'String',
args: {
userId: 'String!',
image: 'Upload'
},
resolve: async (_, { userId, image }) => {
const user = await User.findById({ _id: userId}).exec();
console.log(user);
},
}
};
【问题讨论】:
标签: node.js express mongoose graphql apollo