reactjs 使用graphql-upload、apollo-server-fastify和NestJS代码优先方法上传文件

0g0grzrc  于 4个月前  发布在  React
关注(0)|答案(1)|浏览(46)

使用以下包/技术组合(以及未列出的相应依赖项)从服务器上的客户端接收文件上传的正确实现是什么:

  • 第一个月
  • apollo-server-fastify
  • @nestjs/platform-fastify(代码优先方法)

理想情况下,我们尝试使用NestJS GraphQL Code First技术(除了多个文件而不是一个文件)实现以下内容(从apollo server file uploads开始)

const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type File {
    filename: String!
    mimetype: String!
    encoding: String!
  }

  type Query {
    uploads: [File]
  }

  type Mutation {
    singleUpload(file: Upload!): File!
  }
`;

const resolvers = {
  Query: {
    uploads: (parent, args) => {},
  },
  Mutation: {
    singleUpload: (parent, args) => {
      return args.file.then(file => {
        //Contents of Upload scalar: https://github.com/jaydenseric/graphql-upload#class-graphqlupload
        //file.stream is a node stream that contains the contents of the uploaded file
        //node stream api: https://nodejs.org/api/stream.html
        return file;
      });
    },
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

字符串
现在,我的前端正在使用这种变化正确地将文件发送到我的服务器:

gql`
  mutation uploadObjects($files: [Upload!]!) {
    uploadObjects(files: $files) {
      bucketKey
    }
  }
`;


以下是与预期的文件二进制文件一起发送的请求的图像链接:

a8jjtwal

a8jjtwal1#

你可以在Apollo Server和NestJS的@nestjs/platform-fastify中使用graphql-upload。我们的想法是使用graphql-upload作为一个中间件来处理客户端的文件上传。
首先,您需要更新NestJS的main.ts文件,以便将graphql-upload与Apollo和Fastify集成。

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { graphqlUploadFastify } from 'graphql-upload';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  // Apply the graphql upload middleware
  app.register(graphqlUploadFastify, {
    maxFileSize: 10000000, // 10 MB
    maxFiles: 5,
  });

  await app.listen(3000);
}
bootstrap();

字符串
然后,您需要在GraphQL模块中定义Upload标量,并更新您的解析器和模式以使用Upload标量。下面是一个如何做到这一点的示例。
在您的app.module.ts中:

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { join } from 'path';

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      uploads: false, // Disable the built-in upload functionality of Apollo Server
    }),
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}


接下来,定义你的schema(例如,upload.schema.ts):

import { ObjectType, Field, InputType, Directive } from '@nestjs/graphql';

@ObjectType()
export class File {
  @Field()
  filename: string;

  @Field()
  mimetype: string;

  @Field()
  encoding: string;
}

@InputType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class Upload {
  @Field()
  id: string;
}


以及相应的解析器(例如,upload.resolver.ts):

import { Resolver, Mutation, Args, Query } from '@nestjs/graphql';
import { FileUpload, GraphQLUpload } from 'graphql-upload';
import { createWriteStream } from 'fs';
import { File } from './upload.schema';

@Resolver()
export class UploadResolver {
  @Query(() => [File])
  async uploads(): Promise<File[]> {
    // Implement the logic to return the files
    return [];
  }

  @Mutation(() => Boolean)
  async uploadObjects(@Args({ name: 'files', type: () => [GraphQLUpload] }) files: FileUpload[]): Promise<boolean> {
    await Promise.all(
      files.map(async file => {
        const { createReadStream, filename } = await file;
        // Create a stream to your file destination.
        // Here is an example of saving the file locally
        return new Promise((resolve, reject) =>
          createReadStream()
            .pipe(createWriteStream(`./uploads/${filename}`))
            .on('finish', () => resolve(true))
            .on('error', (error) => reject(error)),
        );
      }),
    );

    return true;
  }
}


在这个实现中,你使用Fastify作为HTTP服务器,而不是默认的(Express)和graphql-upload中间件来处理文件上传。中间件解析传入的文件上传请求,并将流传递到解析器。请注意,在@Mutation装饰器中,我们使用graphql-upload提供的GraphQLUpload,这是文件上传所需的格式。
请确保安装了所有必要的包。如果没有,请使用npm或yarn安装它们:

npm install @nestjs/graphql graphql-tools graphql apollo-server-fastify fastify multipart graphql-upload

相关问题