转发请求头- apollo联邦网关



我使用以下版本:

  • "@apollo/gateway":"^ 2.1.3"
  • "@apollo/server":"^ 4.0.0"
  • "graphql"^ 16.6.0"

我无法获得req对象的处理来提取标题并转发它们。buildService代码用于向下游服务的请求添加头,但ApolloServer上的context始终为空。我尝试了同步和异步,请求而不是请求。我甚至试着直接从context.req.headers中抓取它们,但那是空的。

有谁知道怎么做到这一点吗?

const gateway = new ApolloGateway({
  supergraphSdl: new IntrospectAndCompose({
    subgraphs: [
      { name: "persons", url: process.env.PERSON_SERVER_URL },
    ],
  }),
  buildService({ url }) {
    return new RemoteGraphQLDataSource({
      url,
      willSendRequest: ({ request, context }) => {
        console.log(JSON.stringify(context));
        // TRYING TO INJECT AUTH HEADERS HERE
      }
    });
  }
});
const app = express();
const httpServer = http.createServer(app);
const server = new ApolloServer({
  gateway,
  context: ({ req }) => {
    console.log(JSON.stringify(req));
    // req IS NULL
  },
  plugins: [
    ApolloServerPluginLandingPageDisabled(),
    ApolloServerPluginDrainHttpServer({ httpServer })
  ]
});
await server.start();
const graphqlRoute = "/graphql";
app.use(
  graphqlRoute,
  bodyParser.json(),
  expressMiddleware(server),
);
await new Promise((resolve) => httpServer.listen(process.env.PORT, "0.0.0.0", resolve));
console.log(`🚀 Server ready at ${JSON.stringify(httpServer.address())}`);

为了它的价值,我在这里也问过。这感觉它应该是一个简单的标志(特别是对于联邦)来转发授权头。

你需要从expressMiddleware的请求中读取报头,然后将它们保存在上下文中,然后它们将在willSendRequest中可用,尝试:

const gateway = new ApolloGateway({
  supergraphSdl: new IntrospectAndCompose({
    subgraphs: [
      { name: "persons", url: process.env.PERSON_SERVER_URL },
    ],
  }),
  buildService({ url }) {
    return new RemoteGraphQLDataSource({
      url,
      willSendRequest: ({ request, context }) => {
        console.log(JSON.stringify(context));
        for (const [headerKey, headerValue] of Object.entries(context.headers)) {
          request.http?.headers.set(headerKey, headerValue);
        }
      }
    });
  }
});
const app = express();
const httpServer = http.createServer(app);
const server = new ApolloServer({
  gateway,
  plugins: [
    ApolloServerPluginLandingPageDisabled(),
    ApolloServerPluginDrainHttpServer({ httpServer })
  ]
});
await server.start();
const graphqlRoute = "/graphql";
async function context({ req }) {
  return {
    headers: req.headers,
  };
}
app.use(
  graphqlRoute,
  bodyParser.json(),
  expressMiddleware(server, {context: context}),
);
await new Promise((resolve) => httpServer.listen(process.env.PORT, "0.0.0.0", resolve));
console.log(`🚀 Server ready at ${JSON.stringify(httpServer.address())}`);

在AS4中,ApolloServer有一个不特定于框架的API,并且上下文函数的参数是特定于框架的。la

app.use(
  graphqlRoute,
  cors(),
  bodyParser.json(),
  expressMiddleware(server, {
    context: async ({ req }) => ({
      token: req.headers.authorization
    }),
  }),
);

最新更新