求NestJS中使用GraphQL实现文件上传的示例及完整文档
NestJS + GraphQL 文件上传完整实现示例
没问题!我来给你一步步拆解在NestJS中用GraphQL实现文件上传的流程,亲测可用,比控制器上传多几个关键配置步骤:
1. 安装依赖
首先得装上必要的包,注意Apollo Server 3+不再内置文件上传功能,所以需要额外安装中间件:
npm install graphql-upload @types/graphql-upload
如果你用的是NestJS官方的GraphQL模块(基于Apollo),确保@nestjs/graphql和apollo-server-express版本兼容。
2. 配置GraphQL模块与上传中间件
在app.module.ts里,除了常规的GraphQL配置,还要注册上传标量,同时在main.ts中添加全局上传中间件:
app.module.ts 配置
import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; import { GraphQLUpload } from 'graphql-upload'; import { UploadResolver } from './upload.resolver'; @Module({ imports: [ GraphQLModule.forRoot<ApolloDriverConfig>({ driver: ApolloDriver, autoSchemaFile: true, // 自动生成GraphQL Schema context: ({ req }) => ({ req }), // 传递请求上下文供中间件使用 }), ], providers: [ UploadResolver, // 注册GraphQLUpload标量,让Schema识别上传类型 { provide: 'GraphQLUpload', useValue: GraphQLUpload, }, ], }) export class AppModule {}
main.ts 添加全局中间件
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { graphqlUploadExpress } from 'graphql-upload'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 添加文件上传中间件,可配置最大文件大小、最多文件数量 app.use(graphqlUploadExpress({ maxFileSize: 10 * 1024 * 1024, maxFiles: 10 })); await app.listen(3000); } bootstrap();
3. 创建上传Resolver
接下来写处理文件上传的Resolver,这里以单文件上传为例,多文件上传逻辑类似:
import { Resolver, Mutation, Args } from '@nestjs/graphql'; import { GraphQLUpload, FileUpload } from 'graphql-upload'; import { createWriteStream } from 'fs'; import { join } from 'path'; import { mkdirSync } from 'fs'; @Resolver() export class UploadResolver { @Mutation(() => String) async uploadFile(@Args({ name: 'file', type: () => GraphQLUpload }) file: FileUpload) { const { createReadStream, filename, mimetype } = file; // 确保uploads目录存在,不存在则创建 const uploadDir = join(process.cwd(), 'uploads'); mkdirSync(uploadDir, { recursive: true }); // 定义文件保存路径 const savePath = join(uploadDir, filename); return new Promise((resolve, reject) => { createReadStream() .pipe(createWriteStream(savePath)) .on('finish', () => resolve(`文件上传成功:${filename},类型:${mimetype}`)) .on('error', (err) => reject(`上传失败:${err.message}`)); }); } }
4. 客户端调用示例
如果用Apollo Client,需要配置createUploadLink来支持文件上传:
import { ApolloClient, InMemoryCache, gql } from '@apollo/client'; import { createUploadLink } from 'apollo-upload-client'; const uploadLink = createUploadLink({ uri: 'http://localhost:3000/graphql', }); const client = new ApolloClient({ link: uploadLink, cache: new InMemoryCache(), }); // 上传文件的调用函数 async function uploadLocalFile(file) { const uploadMutation = gql` mutation UploadFile($file: Upload!) { uploadFile(file: $file) } `; try { const result = await client.mutate({ mutation: uploadMutation, variables: { file }, }); console.log('上传结果:', result.data.uploadFile); } catch (err) { console.error('上传出错:', err); } }
注意事项
- 开启GraphQL Playground后,默认就能看到文件选择框,直接测试上传即可。
- 可以替换本地文件写入逻辑,比如上传到云存储(阿里云OSS、AWS S3等),只需要把
createWriteStream的部分换成对应云服务商的SDK调用。 - 根据业务需求调整文件大小、数量限制,避免服务器资源过载。
内容的提问来源于stack exchange,提问作者Sofyan Hadi A.
相关产品推荐
相关产品推荐

