Angular / Nest / GraphQL - 无法上传文件(400 错误请求或 500)

Posted

技术标签:

【中文标题】Angular / Nest / GraphQL - 无法上传文件(400 错误请求或 500)【英文标题】:Angular / Nest / GraphQL - Unable to make file upload (either 400 bad request or 500) 【发布时间】:2020-07-09 01:49:51 【问题描述】:

从我在网上看到的一切都应该可以正常工作,实际上我收到了来自客户的 400 个错误请求和来自邮递员的 500 个(错误的订单)

// app.module.ts
 GraphQLModule.forRoot(
      cors: true,
      playground: true,
      debug: true,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      // installSubscriptionHandlers: true,
      uploads: true,
      context: ( req, res ) => (
        req,
        res,
      ),
// File upload mutation in random resolver
  @Mutation(() => ResponseMessage)
  async uploadSigleFile(
    @Args( type: () => GraphQLUpload, name: 'upload', nullable: true )
    upload: FileUpload,
  ) 
    console.log(upload.filename, upload.mimetype);
    return new ResponseMessage( response: 'ciao' );
  

我启用多部分数据的 Graphql 链接(实际上请求正确显示为多部分)

const uri = `$environment.serverUrl/graphql`; // <-- add the URL of the GraphQL server here
export function createApollo(httpLink: HttpLink): ApolloClientOptions<any> 
  return 
     link: httpLink.create( uri, useMultipart: true ),
    cache: new InMemoryCache()
  ;


@NgModule(
  exports: [ApolloModule, HttpLinkModule],
  providers: [
    
      provide: APOLLO_OPTIONS,
      useFactory: createApollo,
      deps: [HttpLink]
    
  ]
)
export class GraphQLModule 

生成角度服务的Graphql突变

mutation Super($upload: Upload) 
  uploadSigleFile(upload: $upload) 
    response
  

突变被调用的地方(是的,我检查了文件实际上到达了突变)

  onFileChange(e: htmlInputEvent) 
    const myFile = e.target.files[0];
    this.apolloQuery(myFile);
  

  apolloQuery(upload: File) 
    this.superGql
      .mutate(
        upload
      )
      .subscribe(( errors, context, data, extensions ) => 

      );
  

这让我发疯,我将永远感谢任何提供帮助的人,我尝试了任何可能的组合,我不知道我缺少什么(例如:自定义嵌套标量,或将其导入解析器字段, 在客户端使用 apollo-client-upload)

【问题讨论】:

【参考方案1】:

是的,所以最后 apollo 会自动解析多部分请求,并且在代码优先方法中使用标量会导致它被解析 2 次(毫无意义,但无论如何)

所以最后我只需要编写一个上传自定义嵌套标量,完全没有任何作用

import  Scalar, CustomScalar  from '@nestjs/graphql';
// FileUpload is just an interface, not really useful in any way here, just to be // explicit of what type comes out whenever I want to check out the scalar
import  FileUpload  from 'graphql-upload';

@Scalar('Upload')
export class UploadScalar implements CustomScalar<object, any> 
  description = 'Upload custom scalar type';


// the value arrives here already parsed
  parseValue(value: FileUpload) 
    return value;
  


  // You dont use this
  serialize(value: any) 
    return null;
  

  // You dont use this
  parseLiteral(ast) 
    return null;
  

//app.module.ts
GraphQLModule.forRoot(
      autoSchemaFile: join(process.cwd(), 'schema.graphql'),
      context: req => ( req ),
      uploads: true,
    )

// random.resolver.ts
@Query(() => MainObject)
  async boh(
    @Args( name: 'file', type: () => FileUpload, nullable: true )
    file: FileUpload,
  ) 
    return new Promise((resolve, reject) => 
      const read = file.createReadStream();
      const write = fs.createWriteStream(path.join(process.cwd(), 'file3.csv'));
      read.pipe(write);
      read.on('close', () => 
        resolve(new MainObject( response: 'tutto ok', age: 200 ));
      );
    );
  

【讨论】:

以上是关于Angular / Nest / GraphQL - 无法上传文件(400 错误请求或 500)的主要内容,如果未能解决你的问题,请参考以下文章

Nest JS GraphQL“不能为非空返回null” [重复]

如何将firebase时间戳与graphql nest js一起使用?

如何将所有路由重定向到nest.js中的index.html(Angular)?

如何在没有守卫装饰器的情况下始终验证 JWT? (Nest.js + 护照)

Nest.js 获取注入器实例

angular, apollo-client, graphQL - 从 graphql 查询中选择所有字段