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

求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.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:43:45