You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJs中结合GraphQL实现图片上传?解决graphql-upload导入问题

NestJS 图片上传替代方案

方案一:使用 NestJS 内置的 Multer 模块(RESTful 接口)

Multer 是 Express 官方文件上传中间件,NestJS 原生集成,配置简单且稳定性强。

  • 安装依赖:npm install @nestjs/platform-express multer
  • 模块配置示例:
    在模块中导入 MulterModule,指定存储路径与文件过滤规则:
    import { Module } from '@nestjs/common';
    import { MulterModule } from '@nestjs/platform-express';
    import { diskStorage } from 'multer';
    import { extname } from 'path';
    
    @Module({
      imports: [
        MulterModule.register({
          storage: diskStorage({
            destination: './uploads',
            filename: (req, file, cb) => {
              const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
              cb(null, file.fieldname + '-' + uniqueSuffix + extname(file.originalname));
            },
          }),
          fileFilter: (req, file, cb) => {
            if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
              return cb(new Error('仅支持上传图片文件'), false);
            }
            cb(null, true);
          },
        }),
      ],
    })
    export class AppModule {}
    
  • 控制器使用示例:
    import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
    import { FileInterceptor } from '@nestjs/platform-express';
    
    @Controller('upload')
    export class UploadController {
      @Post()
      @UseInterceptors(FileInterceptor('image'))
      uploadFile(@UploadedFile() file: Express.Multer.File) {
        return {
          filename: file.filename,
          path: file.path,
          size: file.size,
        };
      }
    }
    

方案二:使用 Apollo Server 内置文件上传(GraphQL 接口)

若需保留 GraphQL 场景,Apollo Server v3+ 已内置文件上传能力,无需第三方库。

  • 配置 Apollo Server:
    在 GraphQLModule 中开启上传选项:
    import { Module } from '@nestjs/common';
    import { GraphQLModule } from '@nestjs/graphql';
    import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
    
    @Module({
      imports: [
        GraphQLModule.forRoot<ApolloDriverConfig>({
          driver: ApolloDriver,
          autoSchemaFile: true,
          uploads: {
            maxFileSize: 10 * 1024 * 1024, // 限制10MB
            maxFiles: 1,
          },
        }),
      ],
    })
    export class AppModule {}
    
  • 定义 GraphQL 类型与 Resolver:
    GraphQL Schema:
    scalar Upload
    
    type Mutation {
      uploadImage(file: Upload!): FileResponse!
    }
    
    type FileResponse {
      filename: String!
      path: String!
      size: Int!
    }
    
    Resolver 实现:
    import { Args, Mutation, Resolver } from '@nestjs/graphql';
    import { createWriteStream } from 'fs';
    import { extname } from 'path';
    import { FileUpload, GraphQLUpload } from 'graphql-upload';
    
    @Resolver()
    export class UploadResolver {
      @Mutation(() => FileResponse)
      async uploadImage(@Args('file', { type: () => GraphQLUpload }) file: FileUpload) {
        const { createReadStream, filename } = file;
        const uniqueFilename = Date.now() + '-' + Math.round(Math.random() * 1E9) + extname(filename);
        const filePath = `./uploads/${uniqueFilename}`;
    
        return new Promise((resolve, reject) => {
          createReadStream()
            .pipe(createWriteStream(filePath))
            .on('finish', () => resolve({ filename: uniqueFilename, path: filePath, size: file.size }))
            .on('error', (err) => reject(err));
        });
      }
    }
    
    注:若使用 Apollo Server v4,需安装 @apollo/server-plugin-upload 插件并完成对应配置

方案三:集成云存储服务(如 Cloudinary)

无需自行维护存储,直接借助云服务处理文件上传与托管,NestJS 有官方集成包支持。

  • 安装依赖:npm install @nestjs/cloudinary cloudinary
  • 模块配置示例:
    import { Module } from '@nestjs/common';
    import { CloudinaryModule } from '@nestjs/cloudinary';
    import { ConfigModule } from '@nestjs/config';
    
    @Module({
      imports: [
        ConfigModule.forRoot(),
        CloudinaryModule.forRoot({
          isGlobal: true,
          cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
          api_key: process.env.CLOUDINARY_API_KEY,
          api_secret: process.env.CLOUDINARY_API_SECRET,
        }),
      ],
    })
    export class AppModule {}
    
  • 控制器使用示例:
    import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
    import { FileInterceptor } from '@nestjs/platform-express';
    import { CloudinaryService } from '@nestjs/cloudinary';
    
    @Controller('upload')
    export class UploadController {
      constructor(private readonly cloudinaryService: CloudinaryService) {}
    
      @Post('cloud')
      @UseInterceptors(FileInterceptor('image'))
      async uploadToCloudinary(@UploadedFile() file: Express.Multer.File) {
        return this.cloudinaryService.uploadFile(file, {
          folder: 'nest-uploads',
        });
      }
    }
    

内容的提问来源于stack exchange,提问作者Viktor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:35:31