ApolloServer:将 Headers 从请求传递到后端

ApolloServer: Pass Headers From Request Through To Backend

我有一个 ApolloServer,我用它来将多个后端进程拼接在一起——它实际上什么都不做,只是为它们提供一个统一的前端——我希望 headers 在请求中传递(来自来自 React 项目)不受干扰地传递到后端(Clojure 和 Rails)。

我有这个代码:

    let link = new HttpLink({
        uri,
        headers: {"x-api-token": key},
        fetch
    })

而且,也许并不奇怪,后端看到的唯一东西是 "x-api-token"。

我发现我可以从上下文中获取 headers:

const server = async (schema = genSchema) => new ApolloServer({
  schema: await schema(),
  context: (ctx) => ({
    headers: ctx.req.headers
  }),
  extensions: [() => new BasicLogging()]
});

我正试图以某种方式将它们推入即将离任的 headers,但它似乎绕着谷仓走了很长一段路。 (而且我还没有弄清楚,所以我不确定我是否在正确的轨道上。)有没有办法告诉 ApolloServer 只通过请求?

编辑:删除了多余的括号注释。添加代码。

下面是使用在线示例构建的问题的说明:

const { ApolloServer, gql } = require('apollo-server');
var fetch = require('node-fetch')
var {introspectSchema, makeRemoteExecutableSchema} = require('graphql-tools')
var {HttpLink} = require('apollo-link-http')

const genSchema = async () => {
  http = new HttpLink({
    uri: "http://localhost:3000/graphql",
    headers: {"x-api-token": "Whatever"},
    fetch
  })
  const link = setContext((request, previousContext) => ({
    headers: {
      'Authentication': "1234xyz"
    }
  })).concat(http);
  const schema = await introspectSchema(link)
  return makeRemoteExecutableSchema({schema, link})
}

const server = async (schema = genSchema) => new ApolloServer({
  schema: await schema(),
});

exports.startServer = async () => {
  const apolloServer = (await server()).listen({port: process.env.PORT || 4000});
  apolloServer.then(({url}) => console.log(`Server ready at ${url}`));
  return apolloServer
}

将它放在 server.js 中,将下面的放在 index.js 中,你可以 运行 和 "node index.js" (假设你在 locahost:3000 有一个 graphql 服务) :

var server = require('./server')
server.startServer()

您会看到 "x-api-token" 通过,但 "Authentication" 没有。示例代码使用:

'Authentication': `Bearer ${previousContext.graphqlContext.authKey}`,

...我可能会用它来获取 headers 但实际上我输入的任何内容都没有到达服务器端。

好的,我找到了这篇文章:

https://medium.com/wehkamp-techblog/using-headers-with-apollo-datasources-1c4c019d080c

诀窍是在创建服务器时设置上下文,我已经想到了,但是你不能只在 headers 键上 "pass through"。因此,服务器创建可能如下所示:

const server = async (schema = genSchema) => new ApolloServer({
  schema: await schema(),
  context: ({ req }) => ({
    req,
    customHeaders: {
      headers: {
        ...req.headers,
      },
    },
  }),
});

您必须将它们添加到外发邮件中。毫无疑问,您可以将它们全部发送,但由于我现在担心我可能最终会覆盖哪些内容,所以我只取出了一个:

const http = new HttpLink({
  uri: "http://localhost:3000/graphql",
  fetch
})

const link = setContext((request, previousContext) => ({
  headers: {
    'NewHeader': (previousContext.graphqlContext && previousContext.graphqlContext.customHeaders.headers["myheader"]),
  }
})).concat(http);

传入的内容Header"myheader"会在后台出来为"NewHeader"。