如何在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:
Resolver 实现:scalar Upload type Mutation { uploadImage(file: Upload!): FileResponse! } type FileResponse { filename: String! path: String! size: Int! }
注:若使用 Apollo Server v4,需安装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-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
相关产品推荐
相关产品推荐

