如何在apollo-server 4中传递上下文值?

huangapple go评论78阅读模式
英文:

How to pass context value in apollo-server 4?

问题

在 apollo-server 3 中,我能够像这样在创建 apollo 服务器时设置上下文:

const server = new ApolloServer({
    debug: true,
    schema: executableSchema,
    context: contextFunction(secretValues),
...

我的 contextFunction 看起来像这样:

export const contextFunction =
  (secretValues: AwsSecretValues) =>
  async ({ req, res }: ExpressContext) => {
    const sessionId = extractSessionIdFromCookies(req.headers.cookie);
    const session = await validateSession(
      sessionId || req.headers.authorization,
    );

    if (session) {
      session.set({ expiresAt: Date.now() + DEFAULT_SESSION_EXTEND_TIME });
      await session.save();

      generateCookie(session._id, res);
    }

    return {
      pubsub,
      dataLoaders: dataLoaderFactory(),
      session,
      req,
      res,
      secretValues,
    };
  };

这非常有用,因为我不必在每个单独的解析器中独立刷新会话,并且每个解析器都有一个最新的版本,此外,我还能传递一堆其他有用的东西。

从我看来,在 apollo-server 4 中没有这个选项。但是,如果你不能设置上下文,除了将东西传递给子解析器之外,上下文有何意义呢?一定有办法,但我找不到方法。

英文:

In apollo-server 3, I was able to set the context when creating the apollo server like this:

const server = new ApolloServer({
    debug: true,
    schema: executableSchema,
    context: contextFunction(secretValues),
...

My contextFunction looked like this:

export const contextFunction =
  (secretValues: AwsSecretValues) =>
  async ({ req, res }: ExpressContext) => {
    const sessionId = extractSessionIdFromCookies(req.headers.cookie);
    const session = await validateSession(
      sessionId || req.headers.authorization,
    );

    if (session) {
      session.set({ expiresAt: Date.now() + DEFAULT_SESSION_EXTEND_TIME });
      await session.save();

      generateCookie(session._id, res);
    }

    return {
      pubsub,
      dataLoaders: dataLoaderFactory(),
      session,
      req,
      res,
      secretValues,
    };
  };

It was useful, because I didn't have to refresh the session independently at every single resolver, and each resolver had an up-to-date version of it, also I was able to pass in a bunch of other useful stuff.

As I see there's no option for this in apollo-server 4. But what's the whole point of a context if you can't set it (except drilling down stuff to child resolvers)? There must be a way, but cannot find how.

答案1

得分: 5

如文档所述 在文档中,定义相同的新方式如下:

app.use(
  // 如果你不使用ApolloServer<BaseContext>,则需要一个命名上下文函数
  expressMiddleware(server, {
    context: async ({ req, res }) => ({
      token: await getTokenForRequest(req),
    }),
  }),
);
英文:

As stated in the docs, the new way of defining the same is:

app.use(
  // A named context function is required if you are not
  // using ApolloServer&lt;BaseContext&gt;
  expressMiddleware(server, {
    context: async ({ req, res }) =&gt; ({
      token: await getTokenForRequest(req),
    }),
  }),
);

答案2

得分: 0

Apollo Server v4 引入了一种新的上下文数据传递方式,与之前将上下文传递给 ApolloServer 构造函数不同,现在它是通过 Web 集成函数进行传递,如下所示:详细信息请查看链接 https://www.apollographql.com/docs/apollo-server/migration/#context-initialization-function

const { url } = await startStandaloneServer(server, {
  context: async ({ req, res }) => ({
    // 你的数据
  }),
  listen: { port: 4000 },
});
英文:

Apollo Server v4 introduces a new way of passing data with context such that unlike how we were passing context into the ApolloServer constructor, it is now being passed in the web integration function like below: Find more in the link https://www.apollographql.com/docs/apollo-server/migration/#context-initialization-function

const { url } = await startStandaloneServer(server, {
  context: async ({ req, res }) =&gt; ({
    //your data 
});
  listen: { port: 4000 },
});`

huangapple
  • 本文由 发表于 2023年3月9日 15:48:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75681723.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定