【问题标题】:UnhandledPromiseRejectionWarning: Error: You must `await server.start()` before calling `server.applyMiddleware()` at ApolloServerUnhandledPromiseRejectionWarning:错误:在 ApolloServer 调用 `server.applyMiddleware()` 之前必须`await server.start()`
【发布时间】:2021-10-09 07:32:15
【问题描述】:

我正在尝试启动我的 nestJs 服务器,但它一直给我这个错误:

UnhandledPromiseRejectionWarning:错误:您必须先await server.start(),然后再调用server.applyMiddleware() 在 ApolloServer

我什至不知道从哪里调试,因为我还是 NestJs 和 GraphQL 的新手。

【问题讨论】:

  • 在不知道您当前如何运行这些东西的情况下,我们无法为您提供帮助。

标签: error-handling server graphql nestjs apollo


【解决方案1】:

这是一个已知错误,有一个未解决的问题and a merged PR to fix it。目前,您可以降级到apollo-server-express@^2

【讨论】:

  • 非常感谢。现在工作正常
  • 看起来有计划发布@nestjs/graphql@9 来解决这个问题。根据问题,这个重大突破将在@nestjs/core@nestjs/common 重大突破到9 之前很久。但至于何时,我不能说
  • 谢谢@JayMcDoniel 这对我也有用:)
【解决方案2】:

完整的工作代码是:

const express = require("express");
const { ApolloServer } = require("apollo-server-express");
const http = require("http");

const app = express();

const typeDefs = `
    type Query{
        totalPosts: Int!
    }
`;
const resolvers = {
    Query: {
        totalPosts: () => 100,
    },
};
let apolloServer = null;
async function startServer() {
    apolloServer = new ApolloServer({
        typeDefs,
        resolvers,
    });
    await apolloServer.start();
    apolloServer.applyMiddleware({ app });
}
startServer();
const httpserver = http.createServer(app);

app.get("/rest", function (req, res) {
    res.json({ data: "api working" });
});

app.listen(4000, function () {
    console.log(`server running on port 4000`);
    console.log(`gql path is ${apolloServer.graphqlPath}`);
});

【讨论】:

  • 这无需更改 libray 版本即可工作,但不需要以下行: const httpserver = http.createServer(app);
【解决方案3】:

我在升级Ben Awad's Graphql-Next-Typeorm[...] stack 时遇到了这个问题,只需在服务器启动中添加等待即可修复警告

const apolloServer = new ApolloServer({
    introspection: true,
    schema: await buildSchema({
      resolvers: [__dirname + '/resolvers/**/*.js'],
      validate: false
    }),
    context: ({ req, res }) => ({
      req,
      res,
      redis: redisClient
    }),
    formatError
  });


// added this line
  await apolloServer.start();

  apolloServer.applyMiddleware({
    app,
    cors: false
  });

【讨论】:

  • 同样来自 Ben Awad 的课程。 cors: false 确实有帮助,但为什么要关闭 introspection 呢?
  • @BurgerBurglar 我相信你的问题是题外话,内省设置为真,这里有更多关于内省的信息apollographql.com/docs/apollo-server/api/apollo-server/…
  • 我在迁移文档中找不到此信息
  • @EricBurel 我不确定我理解你的意思或暗示,你能详细说明一下吗?
  • 简单地说,Apollo v3 迁移文档并没有很明确地说明需要等待“开始”,或者至少我找不到相关部分,但你的回答很完美
【解决方案4】:

对于 Apollo Server Express 3.0 及更高版本,您需要定义一个接收 typeDefs 和 resolvers 参数的异步函数,然后将服务器分配给与之前相同的 Apollo 初始化,如 here 所示

async function startApolloServer(typeDefs, resolvers){
    const server = new ApolloServer({typeDefs, resolvers})
    const app = express();
    await server.start();
    server.applyMiddleware({app, path: '/graphql'});
    
    app.listen(PORT, () => {
    console.log(`Server is listening on port ${PORT}${server.graphqlPath}`);
})
}

startApolloServer(typeDefs, resolvers);

【讨论】:

    【解决方案5】:

    您可以将所有内容放在异步函数中并在您的服务器(应用程序,索引...).js 中执行该函数。你也可以查看 npm 包。 https://www.npmjs.com/package/apollo-server-express 例如:

    const express = require('express')
        , http = require('http')
        , path = require('path');
    const { ApolloServer } = require('apollo-server-express');
    
    async function startExpressApolloServer() {
    
        const { typeDefs } = require('./graphql/schemas/schema');
        const { resolvers } = require('./graphql/resolvers/resolver');
    
        const server = new ApolloServer({ typeDefs, resolvers });
        await server.start();
    
        const app = express();
        
        server.applyMiddleware({ app, path: '/api/graphql' });
    
        await new Promise(resolve => app.listen({ port: 3001 }, resolve));
        console.log(`Server ready at http://localhost:3001${server.graphqlPath}`);
        return { server, app };
    }
    
    startExpressApolloServer();
    

    【讨论】:

    【解决方案6】:

    另一种选择是将您的 apollo 降级到任何 2.x.x。它解决了我的问题

    【讨论】:

      【解决方案7】:

      提前启动apollo服务器是不行的。当我必须明确使用 http/https 时会发生什么情况。请看以下案例:

        const server = new ApolloServer({
          typeDefs: [KeycloakTypeDefs, typeDefs], // 1. Add the Keycloak Type Defs
          schemaDirectives: KeycloakSchemaDirectives, // 2. Add the
          formatError: new ApolloErrorConverter(),
          resolvers: resolvers,
          context: ({ req }) => {
            return makeContextWithDependencies(req);
          }
        });
        server.applyMiddleware({ app });
      
        http.createServer(app).listen(config.server.port, os.hostname());
        const options = {
          key: fs.readFileSync(config.server.ssl.keyFile, "utf8"),
          cert: fs.readFileSync(config.server.ssl.certFile, "utf8"),
          passphrase: config.server.ssl.passphrase
        };
        https
          .createServer(options, app)
          .listen(config.server.securePort, os.hostname());
        console.log(
          "Server waiting for requests on ports: " +
            config.server.port +
            "," +
            config.server.securePort
        );
      

      【讨论】:

      • 如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。 - From Review
      【解决方案8】:

      这里已经有一些很好的答案。但是我们应该知道为什么以及在哪里调用 server.start()。来自阿波罗文档 -

      在调用之前总是调用 await server.start() server.applyMiddleware 并启动您的 HTTP 服务器。这允许 你通过崩溃你的来对 Apollo Server 启动失败做出反应 进程而不是开始提供流量。

      【讨论】:

        【解决方案9】:

        在 v3 中,如果您使用 apollo-server-express,则需要启动功能https://www.apollographql.com/docs/apollo-server/api/apollo-server/#start

        你可以这样做。

        const app = express()
        app.use(express.urlencoded({ extended: true }))
        app.use(express.json())
        ....
        export const startup = async () => {
          await server.start()
          server.applyMiddleware({ app, path: `/api/${configs.region}/graphql` })
          return app
        }
        
        // call startup in another file to get app
        猜你喜欢
        • 2021-10-07
        • 2021-11-01
        • 1970-01-01
        • 2021-07-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-05
        相关资源
        最近更新 更多