Nestjs graphql 上传错误:缺少 POST 正文。你忘记使用 body-parser 中间件了吗?

Posted

技术标签:

【中文标题】Nestjs graphql 上传错误:缺少 POST 正文。你忘记使用 body-parser 中间件了吗?【英文标题】:Nestjs graphql upload error: POST body missing. Did you forget use body-parser middleware? 【发布时间】:2021-09-05 16:24:42 【问题描述】:

我在节点 v14x 上使用带有 graphql 的 NestJS 7 这是我的 graphql 模块配置

import  Module, NestModule, RequestMethod, MiddlewareConsumer  from '@nestjs/common';
import  graphqlUploadExpress  from "graphql-upload"
import  GraphQLModule  from '@nestjs/graphql';
import  ConfigService  from '@nestjs/config';
import  ApolloServerDataLoaderPlugin  from '@webundsoehne/nestjs-graphql-typeorm-dataloader';
import  GraphqlConfig  from './@core/config/config.interface';
import  getConnection  from 'typeorm';

@Module(
  imports: [
    GraphQLModule.forRootAsync(
      useFactory: async (configService: ConfigService) => 
        const graphqlConfig = configService.get<GraphqlConfig>('graphql');
        return 
          buildSchemaOptions: 
            numberScalarMode: 'integer',
            plugins: [new ApolloServerDataLoaderPlugin( typeormGetConnection: getConnection )]
          ,

          sortSchema: graphqlConfig.sortSchema,
          autoSchemaFile:
            graphqlConfig.schemaDestination || './src/schema.graphql',
          debug: graphqlConfig.debug,
          path: graphqlConfig.endPoint,
          uploads: false,
          playground: graphqlConfig.playgroundEnabled,

          context: ( req, connection ) => 
            if (connection) 
              return  req:  headers: connection.context  
            
            return  req 
          ,
          installSubscriptionHandlers: true,
          dateScalarMode: "isoDate",
          subscriptions: 
            keepAlive: 5000
          
        ;
      ,
      inject: [ConfigService],
    ),

  ],

)
export class GQLModule implements NestModule 

  constructor(private readonly configService: ConfigService)  

  configure(consumer: MiddlewareConsumer) 
    const graphqlConfig = this.configService.get<GraphqlConfig>('graphql');
    consumer.apply(graphqlUploadExpress()).forRoutes(graphqlConfig.endPoint)
  


在文件上传卡在节点 v14.x 上不起作用后,我找到了这个issue comment。我在解析器上从graphql-upload 导入所有内容,但仍然收到POST body missing. Did you forget use body-parser middleware? 之类的错误消息

有人可以帮我吗?

【问题讨论】:

【参考方案1】:

我有几乎相同的配置,它对我来说可以正常工作。由于我同时使用 REST 和 GraphQL,因此我将路由限制为“graphql”

import  MiddlewareConsumer, Module, NestModule  from '@nestjs/common';
import  ServeStaticModule  from '@nestjs/serve-static';
import  MongooseModule  from '@nestjs/mongoose';
import  GraphQLModule  from '@nestjs/graphql';
import  AuthorModule  from '../author/author.module';
import  ApiService  from './api.service';
import  join  from 'path';
const 
  graphqlUploadExpress,
 = require('graphql-upload');

const isLocalEnvironment = () => process.env.ENV === 'local';

console.log('isLocal', isLocalEnvironment(), process.env.ENV);

const modules = [
  AuthorModule,
  
  GraphQLModule.forRoot(
    playground: isLocalEnvironment(),
    fieldResolverEnhancers: ['guards'],
    debug: isLocalEnvironment(),
    autoSchemaFile: isLocalEnvironment() ? 'schema.gql' : true,
    introspection: isLocalEnvironment(),
    useGlobalPrefix: true,
    context: ( req ) => ( req ),
  ),
  MongooseModule.forRoot(process.env.COSMOSDB_CONNECTION_STRING, 
    useNewUrlParser: true,
    useUnifiedTopology: true,
    retryWrites: false,
    autoIndex: true,
  ),
  
];

@Module(
  imports: modules,
  providers: [ApiService],
)
export class APIModule implements NestModule
  configure(consumer: MiddlewareConsumer) 
    consumer.apply(graphqlUploadExpress( maxFileSize: 10000000, maxFiles: 10 )).forRoutes('graphql');
  

在我的 main.ts 文件中,我引导应用程序。

if (process.env.NODE_ENV !== 'production') require('dotenv').config();
import  NestFactory  from '@nestjs/core';
import  APIModule  from './api/api.module';
import  INestApplication  from '@nestjs/common';
import  json, urlencoded  from 'body-parser';
import 'isomorphic-fetch';
const prefix = "api/";
async function bootstrap() 
  const port = process.env.PORT;
  const app: INestApplication = await NestFactory.create(APIModule);
  
  app.enableCors();
  app.use(json( limit: '50mb' ));
  app.use(urlencoded( limit: '50mb', extended: true ));
  // Because I use the global prefix of api/, I need to hit my service at /api/graphql
  app.setGlobalPrefix(prefix);
  console.log('Starting on port ' + port);
  await app.listen(port);
  return app;


bootstrap();

由于您的配置在我看来不错,我猜您的引导函数出了点问题,或者您没有点击 /graphql 路由。

我使用的是最新版本的 NestJS,它不再包含 graphql 上传实现,所以不像你,我不需要关闭上传。

【讨论】:

这对我有用,非常感谢。

以上是关于Nestjs graphql 上传错误:缺少 POST 正文。你忘记使用 body-parser 中间件了吗?的主要内容,如果未能解决你的问题,请参考以下文章

Nestjs 中的 Graphql Apollo 上传返回无效值

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

NestJS:使用 graphql 的 Passport LinkedIn 策略

Nestjs - @nestjs/graphql GraphQLGatewayModule 总是返回错误请求

错误:使用 Nestjs + Graphql + Typeorm 时无法确定 GraphQL 输入类型

从 NestJS + GraphQL 更改 ValidationPipe 错误