【发布时间】:2020-07-09 08:50:30
【问题描述】:
我有一个 ApolloServer,我用它来将多个后端进程拼接在一起——它实际上什么都不做,只是为它们提供了一个统一的前端——我希望在请求中传递的标头(来自 React 项目)传递不受后端(Clojure 和 Rails)影响。
我有这个代码:
let link = new HttpLink({
uri,
headers: {"x-api-token": key},
fetch
})
而且,也许并不奇怪,后端唯一看到的是“x-api-token”。
我发现我可以从上下文中获取标题:
const server = async (schema = genSchema) => new ApolloServer({
schema: await schema(),
context: (ctx) => ({
headers: ctx.req.headers
}),
extensions: [() => new BasicLogging()]
});
我正试图以某种方式将它们推入传出的标题中,但它似乎在谷仓周围很长的路要走。 (而且我还没有弄清楚,所以我不确定我是否走在正确的轨道上。)有没有办法告诉 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}`,
...我可能会用它来获取标头,但实际上我输入的任何内容都没有传递到服务器端。
【问题讨论】:
-
除非您使用 federation 或 schema stitching,否则您是指定如何通过解析器逻辑而不是 Apollo Server 获取数据的人。
-
我正在做模式拼接,是的。
-
我明白了。您必须在服务器级别拉出标头并将它们推入上下文,然后填充传出消息。我稍后会发布完整的答案。
标签: http-headers apollo-server