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"。
我有一个 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"。