问题描述
我正在使用 GraphQL,但遇到了文件上传问题。我的Node版本是v14.16.0
我收到如下错误
错误:未知类型“上传”。您指的是“浮动”吗?
以下是安装的包版本
软件包版本
"dependencies": {
"apollo-server-express": "^2.23.0","bcryptjs": "^2.4.3","compression": "^1.7.4","consola": "^2.15.3","dotenv": "^8.2.0","express": "^4.17.1","graphql-upload": "^11.0.0","jsonwebtoken": "^8.5.1","mongoose": "^5.12.5","nodemon": "^2.0.7","yup": "^0.32.9"
}
以下是我使用 apollo-server-express 和 graphql-upload 包完成的服务器设置
import express from "express";
import consola from "consola";
import { ApolloServer } from "apollo-server-express";
const { error,success } = consola;
import { PORT } from "./config/index.js";
import { typeDefs,resolvers } from "./graphql/index.js";
import * as AppModels from "./models/index.js";
import compression from "compression";
import { graphqlUploadExpress } from "graphql-upload";
//Initialize the app
const app = express();
app.use(compression());
app.use(
graphqlUploadExpress({
maxFileSize: 30000000,maxFiles: 20,})
);
const server = new ApolloServer({
typeDefs,resolvers,uploads: false,context: {
...AppModels,},});
app.use(express.static("public"));
server.applyMiddleware({ app });
app.listen(PORT,() => {
success({
badge: true,message: `Server started at ${PORT}`,});
});
这是我对 imageUpload Mutation 的类型定义
import { gql } from "apollo-server-express";
export default gql`
extend type Mutation {
imageUploader(file: Upload!): String!
}
`;
我的解析器看起来像这样
import { createWriteStream } from "fs";
import { parse,join } from "path";
import { URL } from "../../config/index.js";
export default {
Mutation: {
imageUploader: async (_,{ file }) => {
let { filename,createReadStream } = await file;
let stream = createReadStream();
let { name,ext } = parse(filename);
name = name.replace(/([^a-z0-9 ]+)/gi,"-").replace(" ","_");
let serverFile = `D:/${name}${ext}`;
let writeStream = await createWriteStream(serverFile);
await stream.pipe(writeStream);
//serverFile = `${URL}/${serverFile.split("uploads")[1]}`;
return serverFile;
},};
解决方法
好吧,这适合任何面临这种情况的人
因为我们使用的是 graphl-upload 包,所以我们需要在 typedef 中定义自定义标量并在解析器中分配上传类型。
所以现在我的 typedef 看起来像这样。注意代码标量上传
import { gql } from "apollo-server-express";
export default gql`
scalar Upload
extend type Mutation {
imageUploader(file: Upload!): String!
}
`;
在 typedef 更改后,我们需要为该标量定义一个解析器。所以现在解析器看起来像这样
import { createWriteStream } from "fs";
import { GraphQLUpload } from "graphql-upload";
import { parse,join } from "path";
import { URL } from "../../config/index.js";
export default {
Upload: GraphQLUpload,Mutation: {
imageUploader: async (_,{ file }) => {
let { filename,createReadStream } = await file;
let stream = createReadStream();
let { name,ext } = parse(filename);
name = name.replace(/([^a-z0-9 ]+)/gi,"-").replace(" ","_");
let serverFile = `D:/${name}${ext}`;
let writeStream = await createWriteStream(serverFile);
await stream.pipe(writeStream);
//serverFile = `${URL}/${serverFile.split("uploads")[1]}`;
return serverFile;
},},};
以上代码帮助我解决了这个问题。