graphql - 如何使用 nestjs-graphql-fastify 服务器上传文件以及如何测试该功能?

标签 graphql nestjs fastify

我很难将 .csv 文件上传到 nestjs-graphql-fastify 服务器。尝试了以下代码:

  @Mutation(() => Boolean)
  async createUsers(
    @Args({ name: 'file', type: () => GraphQLUpload })
    { createReadStream, filename }: FileUpload,
  ): Promise<boolean> {
    try {
      // backend logic . . .
    } catch {
      return false;
    }
    return true;
  }

但是我在使用 postman 进行测试时得到的只是这个响应:

{
    "statusCode": 415,
    "code": "FST_ERR_CTP_INVALID_MEDIA_TYPE",
    "error": "Unsupported Media Type",
    "message": "Unsupported Media Type: multipart/form-data; boundary=--------------------------511769018912715357993837"
}

使用代码优先方法进行开发。

更新:尝试使用 fastify-multipart 但问题仍然存在。改变的是 postman 的回应:

POST body missing, invalid Content-Type, or JSON object has no keys.

最佳答案

在 Nestjs discord channel 上找到了一些答案。

您必须进行以下更改:

主要.ts

async function bootstrap() {
  const adapter = new FastifyAdapter();
  const fastify = adapter.getInstance();

  fastify.addContentTypeParser('multipart', (request, done) => {
    request.isMultipart = true;
    done();
  });
  fastify.addHook('preValidation', async function (request: any, reply) {
    if (!request.raw.isMultipart) {
      return;
    }

    request.body = await processRequest(request.raw, reply.raw);
  });

  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    adapter,
  );


  await app.listen(apiServerPort, apiServerHost);
}

bootstrap();

上传.标量.ts

import { Scalar } from '@nestjs/graphql';
import { GraphQLUpload } from 'graphql-upload';

@Scalar('Upload')
export class UploadGraphQLScalar {
  protected parseValue(value) {
    return GraphQLUpload.parseValue(value);
  }

  protected serialize(value) {
    return GraphQLUpload.serialize(value);
  }

  protected parseLiteral(ast) {
    return GraphQLUpload.parseLiteral(ast, ast.value);
  }
}

用户.resolver.ts

  @Mutation(() => CreateUsersOutput, {name: 'createUsers'})
  async createUsers(
    @Args('input', new ValidationPipe()) input: CreateUsersInput,
    @ReqUser() reqUser: RequestUser,
  ): Promise<CreateUsersOutput> {
    return this.usersService.createUsers(input, reqUser);
  }

创建共享.input.ts

@InputType()
export class DataObject {
  @Field(() => UploadGraphQLScalar)
  @Exclude()
  public readonly csv?: Promise<FileUpload>;
}

@InputType()
@ArgsType()
export class CreateUsersInput {
  @Field(() => DataObject)
  public readonly data: DataObject;
}

另外,我想提一下你不应该使用全局验证管道(在我的例子中它们使文件不可读)

  // app.useGlobalPipes(new ValidationPipe({ transform: true }));

关于graphql - 如何使用 nestjs-graphql-fastify 服务器上传文件以及如何测试该功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70340273/

相关文章:

javascript - 如何访问 Fastify 请求的原始正文?

javascript - Fastify 中间件 - 访问查询和参数?

java - apollo-android可以作为java客户端使用吗?

graphql - Prisma Playground 给出 token 无效错误

javascript - graphqljs - 如何搜索枚举类型

javascript - 如何列出 Nestjs DTO 类的属性?

typescript - TypeORM:如何使用查询运行器部分更新给定的实体?

node.js - NestJS 返回 HTTP 请求的结果

javascript - 如何在使用 fastify 服务之前替换 Javascript 变量?

graphql - 尝试在 AWS AppSync 中删除时出错