在GraphQL中,context
是一个在所有解析器之间共享的对象,它携带了在处理一个特定请求时可能需要的跨解析器的信息。这允许您在整个请求期间传递信息和依赖项,例如用户认证信息、数据库连接或其他服务。
作用和好处
- 跨解析器共享数据 :
context
可以在所有解析器间共享数据,这对于需要在多个解析器中访问相同信息的情况非常有用。 - 隔离请求特定的信息 :每个请求都会生成一个新的
context
对象,因此它适合存储请求特定的信息(如当前登录的用户)。 - 安全性和隔离 :使用
context
来传递信息更安全,因为它避免了全局状态,并且可以隔离不同请求的数据。
代码示例
假设您有一个GraphQL服务,需要访问数据库并知道当前的用户。以下是一个如何设置和使用context
的示例:
设置GraphQL Server
假设您使用的是Apollo Server:
typescript
// npm install @apollo/server express graphql cors
import { ApolloServer } from '@apollo/server';
import { expressMiddleware } from '@apollo/server/express4';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'; import express from 'express';
import http from 'http';
import cors from 'cors';
import { typeDefs, resolvers } from './schema';
interface MyContext {
token?: String;
}
const app = express();
const httpServer = http.createServer(app);
const server = new ApolloServer<MyContext>({
typeDefs,
resolvers,
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
await server.start();
app.use(
'/graphql',
cors<cors.CorsRequest>(),
express.json(),
expressMiddleware(
server,
{ context: async ({ req }) => ({ token: req.headers.token }), }),
);
await new Promise<void>((resolve) => httpServer.listen({ port: 4000 }, resolve));
console.log(`🚀 Server ready at http://localhost:4000/graphql`);
在这个例子中,每个进入的请求都会执行context
函数。这个函数从请求头中获取认证信息,验证用户,并将数据库连接和用户对象放入context
。
在解析器中使用Context
然后在解析器中,您可以访问这些context
中的信息:
javascript
const resolvers = {
Query: {
currentUser: (_, __, context) => {
return context.user;
},
getPosts: (_, __, context) => {
return context.db.getPosts();
}
}
};
在这里,currentUser
查询将返回当前请求中的用户信息,而getPosts
查询将使用context
中的数据库连接来获取帖子。
总结
context
在GraphQL中作为一种将请求特定的信息(如用户身份和数据库连接)传递给解析器的机制。它增加了代码的模块化和安全性,使得每个解析器都能访问需要的共享资源和信息,而不需要创建全局变量或进行不必要的参数传递。
问题:context必须初始化时设置才能访问到吗?
在GraphQL中,context
是一种向所有解析器传递信息的机制,通常是在GraphQL服务器初始化时设置的。在Apollo Server中,这是通过在ApolloServer
构造函数中提供context
属性来实现的。
Apollo Server中的context
设置
在Apollo Server中,context
是在每个请求的基础上创建的,并在请求的所有解析器之间共享。这意味着您需要在服务器初始化时定义context
,这样才能在解析器中访问到它。
解析器中访问context
解析器函数的第三个参数就是context
。如果您没有在Apollo Server初始化时设置context
,则默认的context
将是一个空对象,或者仅包含Apollo Server自动提供的基本字段。
示例中的访问
在您的示例中:
javascript
javascriptCopy code
currentUser: (_, __, context) => {
return context.user;
},
getPosts: (_, __, context) => {
return context.db.getPosts();
}
这里的解析器依赖于context
来访问user
和db
对象。如果在Apollo Server初始化时没有设置这些对象,解析器将无法访问context.user
和context.db
。
结果
- 设置了
context
:如果您在Apollo Server设置了context
(如通过验证用户信息和添加数据库连接),那么解析器就能访问到这些信息。 - 未设置
context
:如果未在Apollo Server中设置context
,或者设置的context
中不包含特定的字段(如user
或db
),解析器中尝试访问这些字段时将返回undefined
,可能导致错误。
总结
context
的正确设置对于在GraphQL解析器中访问请求特定的信息至关重要。如果您依赖于context
中的某些信息,务必在Apollo Server初始化时正确设置这些信息。这是确保您的GraphQL API功能正常的关键部分。