GraphQL 是一种用于 API 的查询语言和运行时环境,它提供了一种更加高效、强大和灵活的方式来构建 API。在 GraphQL 中,中间件是一种非常重要的概念,它可以用来实现各种功能,包括请求验证、缓存、日志记录、性能监控等。
什么是中间件?
中间件是一种在请求和响应之间执行的函数,它可以访问请求对象和响应对象,并且可以修改它们或者执行一些其他的操作。在 GraphQL 中,中间件通常被用来实现一些非常常见的功能,比如请求验证、缓存、日志记录、性能监控等。
中间件的应用
请求验证
在 GraphQL 中,请求验证是一种非常常见的需求,它可以用来保护 API 的安全性。例如,我们可以使用中间件来验证请求中的身份信息、权限信息等。下面是一个简单的例子:
// javascriptcn.com 代码示例 const { ApolloServer, gql } = require('apollo-server'); const jwt = require('jsonwebtoken'); const typeDefs = gql` type Query { hello: String } `; const resolvers = { Query: { hello: () => 'world', }, }; const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { const token = req.headers.authorization || ''; try { const user = jwt.verify(token, 'secret-key'); return { user }; } catch (err) { return {}; } }, }); server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
在上面的例子中,我们使用了 jsonwebtoken
库来验证请求中的身份信息。具体来说,我们在 context
函数中获取请求头中的 authorization
字段,然后使用 jsonwebtoken.verify
方法来验证该字段是否合法。如果验证成功,我们将用户信息存储在 context
中,这样在后续的解析过程中就可以使用它了。
缓存
在 GraphQL 中,缓存是一种非常重要的优化手段,它可以大大提高 API 的性能。例如,我们可以使用中间件来缓存查询结果,这样在后续的查询中就可以直接使用缓存结果,而不需要重新执行查询。下面是一个简单的例子:
// javascriptcn.com 代码示例 const { ApolloServer, gql } = require('apollo-server'); const apolloCache = require('apollo-cache'); const Redis = require('ioredis'); const typeDefs = gql` type Query { hello: String } `; const resolvers = { Query: { hello: () => 'world', }, }; const cache = new apolloCache.InMemoryCache(); const redis = new Redis(); const server = new ApolloServer({ typeDefs, resolvers, cache, context: ({ req }) => { return { redis }; }, plugins: [ { async requestDidStart(requestContext) { const { query, variables } = requestContext.request; const key = JSON.stringify({ query, variables }); const cachedResult = await requestContext.context.redis.get(key); if (cachedResult) { requestContext.response = { data: JSON.parse(cachedResult), }; } return { async willSendResponse(requestContext) { if (!requestContext.response.errors) { const { query, variables } = requestContext.request; const key = JSON.stringify({ query, variables }); await requestContext.context.redis.set( key, JSON.stringify(requestContext.response.data), 'EX', 60 ); } }, }; }, }, ], }); server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
在上面的例子中,我们使用了 apollo-cache
库来实现缓存功能。具体来说,我们在 plugins
中注册了一个中间件,该中间件会在请求开始时检查是否有缓存结果,如果有,则直接返回缓存结果,否则继续执行查询。在查询结束时,我们会将结果缓存到 Redis 中,这样在后续的查询中就可以直接使用缓存结果了。
日志记录
在 GraphQL 中,日志记录是一种非常重要的调试手段,它可以帮助我们快速定位问题。例如,我们可以使用中间件来记录每个请求的详细信息,包括请求时间、请求参数、响应时间、响应结果等。下面是一个简单的例子:
// javascriptcn.com 代码示例 const { ApolloServer, gql } = require('apollo-server'); const typeDefs = gql` type Query { hello: String } `; const resolvers = { Query: { hello: () => 'world', }, }; const server = new ApolloServer({ typeDefs, resolvers, plugins: [ { async requestDidStart(requestContext) { console.log(`Request started: ${requestContext.request.operationName}`); console.log(`Request query: ${requestContext.request.query}`); console.log(`Request variables: ${JSON.stringify(requestContext.request.variables)}`); return { async willSendResponse(requestContext) { console.log(`Request finished: ${requestContext.request.operationName}`); console.log(`Response data: ${JSON.stringify(requestContext.response.data)}`); }, }; }, }, ], }); server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
在上面的例子中,我们在 plugins
中注册了一个中间件,该中间件会在请求开始时打印请求信息,包括操作名称、查询语句和变量。在请求结束时,我们会打印响应结果,这样就可以方便地调试和定位问题了。
总结
中间件是 GraphQL 中非常重要的概念,它可以用来实现各种功能,包括请求验证、缓存、日志记录、性能监控等。在实际开发中,我们可以根据自己的需求来编写中间件,从而实现更加高效、强大和灵活的 API。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65607e45d2f5e1655dab0ae2