如何扩展 GraphQL 调用的上下文对象?

How to extend the context object of a GraphQL call?

我在标准模块中调用了以下 GraphQL 服务器:

export default () => {
    return graphqlHTTP({
        schema: schema,
        graphiql: true,
        pretty: true,
        formatError: error => ({
            message: error.message,
            locations: error.locations,
            stack: error.stack,
            path: error.path
        })
    });
};

与护照一起使用的:

app.use(
    "/graphql",
    passport.authenticate("jwt", { session: false }),
    appGraphQL()
);

一切都是工作文件。 Passport 扩展了我的 req 以获取记录的用户对象,该对象用于我的 GraphQL 查询或变更调用:

...
    resolve(source, args, context) {
        console.log("CURRENT USER OBJECT")
        console.log(context.user)
...

一切顺利。

现在我需要扩展我的上下文以添加一些自定义解析器,所以我的第一个尝试是:

export default () => {
    return graphqlHTTP({
        schema: schema,
        graphiql: true,
        pretty: true,
        context: resolvers,
        formatError: error => ({
            message: error.message,
            locations: error.locations,
            stack: error.stack,
            path: error.path
        })
    });
};

正如 GraphQL 文档所说,这会覆盖原始请求上下文,并且我的 context.user 查询和突变停止工作。

如何正确扩展当前上下文以添加更多字段,而不是覆盖它?另一个不成功的尝试:

export default (req) => {
    return graphqlHTTP({
        schema: schema,
        graphiql: true,
        pretty: true,
        context: {
            user: req.user,
            resolvers: resolvers
        },
        formatError: error => ({
            message: error.message,
            locations: error.locations,
            stack: error.stack,
            path: error.path
        })
    });
};

此方法无效...我收到以下错误:

  user: req.user,
                ^

TypeError: Cannot read property 'user' of undefined

[编辑] 我最近的尝试来自我在 Apollo Docs:

上的示例
export default () => {
    return graphqlHTTP({
        schema: schema,
        graphiql: true,
        pretty: true,
        context: ({ req }) => ({
            user: req.user
        }),
        formatError: error => ({
            message: error.message,
            locations: error.locations,
            stack: error.stack,
            path: error.path
        })
    });
};

现在我的上下文是解析器中的一个函数:

console.log(context)
console.log(context.user)

Returns:

[Function: context]
undefined

为这个简单的事情发疯...

假设您使用的是 express-graphqlgraphqlHTTP 是一个接受一些配置参数的函数,returns 是一个快速中间件函数。通常,它是这样使用的:

app.use(
  '/graphql',
  graphqlHTTP({ ... })
)

但是,graphqlHTTP 还可以采用 一个函数,该函数 returns 一个对象,如 docs 所示。

app.use(
  '/graphql',
  graphqlHTTP((req, res, graphQLParams) => {
    return { ... }
  })
)

这样,您可以在配置对象中使用 reqresgraphQLParams 参数。

app.use(
  '/graphql',
  graphqlHTTP((req, res, graphQLParams) => {
    return {
      schema,
      // other options
      context: {
        user: req.user,
        // whatever else you want
      }
    }
  })
)