未知类型“上传”——Apollo Server Express with graphql-upload Node 14

问题描述

我正在使用 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;
    },},};

以上代码帮助我解决了这个问题。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...