首页 > 解决方案 > express GraphQL中根值和上下文的区别

问题描述

我正在浏览 GraphQL-Express 文档,在这些文档中有一个 rootValue 和 Context 的定义,看起来像这样

rootValue:作为 rootValue 从 GraphQL.js/src/execute.js 传递给 graphql() 函数的值。

context:作为上下文传递给 GraphQL.js/src/execute.js 中的 graphql() 函数的值。如果未提供上下文,则将请求对象作为上下文传递。

现在,有人可以解释一下上面的 rootValue 和 context 之间的区别吗?

另外,由于我也是 Express-and-GraphQL 的新手。

我在网上读到的例子,那里的人做了这样的事情

// GraphQL setup
app.use("/user", async  (req, res) => graphqlHTTP({
  schema: userSchema, //TODO: Change it authentication once it is ready
  graphiql: true,
  context: {req, res}
})(req, res)) 

请注意 })(req, res))上面的行中看起来像这样的行,我认为它是一个自行调用的 annyonmousfunction?

在官方 express GraphQL 示例中,我找不到类似的内容,即从官方文档中引用

app.use(
  '/graphql',
  graphqlHTTP(async (request, response, graphQLParams) => ({
    schema: MyGraphQLSchema,
    rootValue: await someFunctionToGetRootValue(request),
    graphiql: true,
  })),

这里为什么我们没有使用匿名函数?是因为将值传递给上下文还是将值传递给根?

标签: node.jsgraphql

解决方案


在 GraphQL.js 中,上下文是一个特定于服务的对象,它被传递给架构中的每个解析器。它建立在每个请求的基础上,因此可以包括会话信息、有关发出请求的用户的信息等。它也常用于依赖注入。例如,您通常会看到传递给上下文的数据库模型,因此它们可以在解析器内部访问,而无需访问require它们的模块。

每个解析器都将其父字段解析为的值作为其第一个参数传递。对于像or类型的根级别字段,没有父字段。该值只是传递给这些解析器的值。在我看来,很少需要通过根值提供任何值。QueryMutationroot

Express 使用接受三个参数(req、res、next)或四个参数(error、req、res、next)的中间件函数。你传递给的app.use应该是一个中间件函数。该graphqlHTTP函数本身不是一个中间件函数——它返回一个中间件函数。

考虑以下示例:

const foo = (req, res, next) => {
  res.status(200)
}
app.use(foo)

// Here the function inside app.use is the actual middleware, but it passes
// the values it receives to foo
app.use((req, res, next) => foo(req, res, next))

// This returns a middleware function
const bar = () => {
  return (req, res, next) => {
    res.status(200)
  }
}
// Notice we have to call bar first, just like we do with graphqlHTTP
app.use(bar())

// We can "wrap" bar inside another middleware function like we did with foo
app.use((req, res, next) => bar()(req, res, next))

这四个示例是等效的,因为它们都做同样的事情(在请求中将状态设置为 200)。

给定一个中间件函数,或者一个返回一个的函数,通常没有必要将它“包装”或“嵌套”在另一个中间件中。但是,在您的示例中,我们希望在调用之前访问req并生成将要使用的实际中间件函数,因此我们必须这样做。resgraphqlHTTP

但是,这也是不必要的,因为它本身接受一个将和值作为参数graphqlHTTP传递的函数。我认为在某一时刻没有包含在回调函数中,所以在这些情况下这是一个合适的解决方法。reqresres


推荐阅读