如何在apollo-server-express中启用@defer指令
你当前的配置存在两处明显问题:仅在runHttpQuery参数中加enableDefer: true不足以完整启用@defer指令,同时你写的runHttpQuery调用逻辑没有处理返回的响应结果,客户端将无法收到返回内容。需要补充以下配置:
1. 确认依赖版本
@defer指令从Apollo Server v4版本开始提供稳定支持,如果你使用的是v3及更低版本需要先升级依赖。
2. ApolloServer实例层面开启支持
构造ApolloServer实例时需要显式开启流式响应权限,示例配置:
import { ApolloServer } from '@apollo/server'; import { ApolloServerPluginInlineTraceDisabled } from '@apollo/server/plugin/disabled'; const server = new ApolloServer({ typeDefs, resolvers, // 启用分片响应,是@defer生效的前提 allowBatchedHttpResponses: true, // 关闭内置链路追踪避免和流式响应冲突 plugins: [ApolloServerPluginInlineTraceDisabled()], });
3. 补全graphqlHandler的响应处理逻辑
你当前的代码调用runHttpQuery后没有处理返回的流式响应,需要修改为如下写法:
const graphqlHandler = async ( req: express.Request, res: express.Response, next ) => { try { const httpGraphQLResponse = await runHttpQuery([req, res], { method: req.method, options: typeof options === 'function' ? await options(req, res) : options, query: req.method === "POST" ? req.body : req.query, request: convertNodeHttpToRequest(req), enableDefer: true, }); // 写入响应头 for (const [headerName, headerValue] of httpGraphQLResponse.headers) { res.setHeader(headerName, headerValue); } res.status(httpGraphQLResponse.statusCode); // 将流式响应体回传给客户端 httpGraphQLResponse.body.pipe(res); } catch (error) { next(error); } };
额外注意事项
- 客户端必须支持
multipart/mixed格式的响应,Apollo Client v3.7+、Relay等主流GraphQL客户端均已适配,低版本客户端无法接收@defer拆分的增量响应块 - 如果服务前置了Nginx等反向代理,需要关闭代理层的响应缓冲,否则流式响应会被缓存后一次性返回,失去@defer的增量加载效果,Nginx对应配置如下:
proxy_buffering off;
proxy_cache off;
- 全局中间件不要提前结束响应或者修改响应体结构,否则会破坏流式响应的格式
内容的提问来源于stack exchange,提问作者user16295068
相关产品推荐
相关产品推荐

