apollo-server 和 apollo-server-express 在 GraphQL 端点上的区别

Difference on GraphQL endpoint between apollo-server and apollo-server-express

由于我需要为我的 GraphQL 服务器添加更多配置,我从 apollo-server 切换到 apollo-server-express (as recommended by the documentation)。

这是我的老index.ts:

import { env } from 'process'
import { ApolloServer } from 'apollo-server'
import { typeDefs } from '../graphql/schema'
import { context } from './context'
import resolvers from '../graphql/resolvers/'

const port = env.GRAPHQL_SERVER_PORT || 80

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context
})

server.listen({ port: port }).then(({ url }) => {
  console.log(`Server ready at ${url}`)
})

这就是我现在要做的事情:

import { env } from 'process'
import { ApolloServer } from 'apollo-server-express';
import { ApolloServerPluginDrainHttpServer } from 'apollo-server-core';
import express from 'express';
import { forceDomain } from 'forcedomain'
import http from 'http';
import { typeDefs } from '../graphql/schema'
import { context } from './context'
import resolvers from '../graphql/resolvers/'

async function startApolloServer(typeDefs: any, resolvers: any, context: any) {
  const port = env.GRAPHQL_SERVER_PORT || 80
  const app = express();
  const httpServer = http.createServer(app);
  const plugins = [ApolloServerPluginDrainHttpServer({ httpServer })]

  const server = new ApolloServer({
    typeDefs,
    resolvers,
    context,
    plugins,
  });

  await server.start();

  app.use(function(req, res, next) {
    // some extra middleware configuration here
  })

  server.applyMiddleware({ app })

  await new Promise<void>(resolve => httpServer.listen({ port: port }, resolve))
  console.log(`Server ready at http://localhost:${port}${server.graphqlPath}`)
}

startApolloServer(typeDefs, resolvers, context)

我不明白的是,在切换到 apollo-server-express 之后,一切正常(并且添加的中间件完成了我需要它做的事情)但是 GraphQL 端点移到了 /graphql 路由(即 http://localhost:4000/graphqlhttps://my-devel-server.com/graphql),而不是像以前那样位于根目录下(所以只是 http://localhost:4000),当我使用 apollo-serverlisten方法。

为什么会这样,我如何使用 apollo-server-express 同时将端点保留在服务器的根目录中?

我不确定为什么中间件在没有看到您如何实现它们的情况下现在可以工作,但是“GraphQL 中间件”与“Express 中间件”有很大不同,所以也许这是它们的结构方式。

关于路由,在 /graphql 处创建基本 GraphQL 路由只是一个标准,因为在 Express 应用程序中,您可能在根目录中有其他 REST 路由。

要更改此行为,您可以将 server.applyMiddleware({ app }) 行更改为 server.applyMiddleware({ app, path: '/' }) 以及您希望 GraphQL 启动的路径。