Apollo 订阅服务器返回“必须提供文件”。

Posted

技术标签:

【中文标题】Apollo 订阅服务器返回“必须提供文件”。【英文标题】:Apollo Subscription Server returns "Must provide document." 【发布时间】:2021-12-15 17:01:41 【问题描述】:

我们公司昨天迁移到 Apollo v3 (apollo-server-express v3.4.0)。

很遗憾,订阅会返回以下响应:

 "message": "Must provide document" 

我们做了以下观察:

    这是一个服务器问题,因为我们在使用 Apollo Studio 时也遇到了这个错误。 连接已建立,服务器触发 onConnect 事件。 请求触发 onOperation 事件并带有正确的消息。 但从不调用订阅的订阅事件。

这是我的 index.mjs:

import  ApolloServer  from 'apollo-server-express';
import express from 'express';
import http from 'http';
import cors from 'cors';
import  execute, subscribe  from 'graphql';
import  graphqlUploadExpress  from 'graphql-upload';
import  SubscriptionServer  from 'subscriptions-transport-ws';
import  makeExecutableSchema  from '@graphql-tools/schema';

import typeDefs from './moduleHandler/graphqlModule/typeDefs.mjs';
import resolvers from './moduleHandler/graphqlModule/resolvers.mjs';


const expressApp = express();
const corsOptions = 
  origin: (origin, callback) => 
    callback(null, true);
    return;
  ,
  credentials: true
;

expressApp.use(cors(corsOptions));
expressApp.use(graphqlUploadExpress( ));

const httpServer = http.createServer(expressApp);

const schema = makeExecutableSchema( typeDefs, resolvers );

const subscriptionServer = SubscriptionServer.create(
  schema,
  execute,
  subscribe,
  onConnect: async (connectionParams, webSocket) =>  // subscriptions
    console.log('on Connect')  // fires
    return  
  ,
  onOperation: async (_message, params, ws) => 
    console.log(_message)  // fires
    /* prints my subcription:
        
    id: '23',
       type: 'start',
       payload: 
         query: 'subscription Subscription($category: ConversationOverviewCategory!) \n' +
           '  conversationOverviewListen(category: $category) \n' +
           '    item \n' +
           '      base  _id \n' +
           '    \n' +
           '  \n' +
           '',
         operationName: 'Subscription',
         variables:  category: 'ALL' 
       
     
    */
    return params;
  , 
  server: httpServer,
  path: '/subscriptions'
);

const apolloServer = new ApolloServer(
  schema,
  playground: false,
  resolverValidationOptions: 
    requireResolversForResolveType: false
  ,
  formatError: err => 
    console.log(err); // not called
  ,
  plugins: [
    async serverWillStart() 
      return 
        async drainServer() 
          console.log('bye');  // not called
          subscriptionServer.close();
        
      ;
    
  ],
  uploads: false,
  path: '/graphql'
);

await apolloServer.start();
apolloServer.applyMiddleware( app: expressApp, cors: corsOptions, path: '/graphql' );

httpServer.listen(80, async () => 
  httpServer.setTimeout(1 * 60000) // 1 min
  console.log('started');  // called
);

我的解析器.mjs:

export default 
  Subscription: 
   conversationOverviewListen: 
    subscribe: () => console.log("never called"),
  
;

我们很乐意提供任何帮助。谢谢!!

【问题讨论】:

你有没有在不降级的情况下解决这个问题? 【参考方案1】:

降级到 apollo-server-express v3.1.2 解决了这个问题。

【讨论】:

以上是关于Apollo 订阅服务器返回“必须提供文件”。的主要内容,如果未能解决你的问题,请参考以下文章

嵌套在类型中的 Apollo 服务器订阅

Apollo 服务器订阅不起作用

AWS 云中带有订阅的 Apollo GraphQL 服务器

如何在 apollo 订阅服务器上获取客户端 IP 地址?

通过 apollo 连接到 graphql-yoga 服务器进行订阅的正确方法是啥?

外部 WebSocket 服务器上的 Apollo-Server GraphQL 订阅