将上传类型添加到 GraphQL
Add Upload type to GraphQL
我正在尝试创建一个自定义解析器来为使用 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`);
^
Error: Type with name "Upload" 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: '/',
});
...
- 我在架构索引中提供了以下代码:
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);
},
}
};
如文档所述:
Note: When using typeDefs, Apollo Server adds scalar Upload to your schema, so any existing declaration of scalar Upload in the type definitions should be removed. If you create your schema with makeExecutableSchema and pass it to ApolloServer constructor using the schema param, make sure to include scalar Upload.
如果您不使用 typeDefs
和 resolvers
选项而是将 schema
直接传递给 ApolloServer
的构造函数,则必须添加标量你自己。 graphql-compose
的文档显示 how to do this 但它应该像这样简单:
import { schemaComposer } from 'graphql-compose'
import { GraphQLUpload } from 'apollo-server'
schemaComposer.add(GraphQLUpload)
我正在尝试创建一个自定义解析器来为使用 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`); ^
Error: Type with name "Upload" 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: '/',
});
...
- 我在架构索引中提供了以下代码:
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);
},
}
};
如文档所述:
Note: When using typeDefs, Apollo Server adds scalar Upload to your schema, so any existing declaration of scalar Upload in the type definitions should be removed. If you create your schema with makeExecutableSchema and pass it to ApolloServer constructor using the schema param, make sure to include scalar Upload.
如果您不使用 typeDefs
和 resolvers
选项而是将 schema
直接传递给 ApolloServer
的构造函数,则必须添加标量你自己。 graphql-compose
的文档显示 how to do this 但它应该像这样简单:
import { schemaComposer } from 'graphql-compose'
import { GraphQLUpload } from 'apollo-server'
schemaComposer.add(GraphQLUpload)