ApolloGateway:接收响应后如何发起GraphQL调用
实现方案分析
方案一:基于didReceiveResponse的直接实现
这是贴合Apollo DataSource生命周期的常规方案,步骤清晰可控:
- 先获取原始请求的响应,判断该请求是否为变更(Mutation)且执行成功
- 解析响应体,提取后续请求所需的参数
- 发起第二个GraphQL变更请求
代码示例:
class SomeRemoteGraphQLDataSource extends RemoteGraphQLDataSource { async didReceiveResponse(response, req, context) { const body = await super.didReceiveResponse(response, req, context); // 检查原始请求是否为Mutation且执行成功 const isMutation = req.operationName?.includes('Mutation') || req.body.query?.startsWith('mutation'); const isSuccess = !body.errors; if (isMutation && isSuccess) { // 解析响应数据,提取后续请求需要的参数(示例:假设返回了创建后的用户ID) const userId = body.data?.createUser?.id; if (userId) { // 发起第二个Mutation请求 try { await this.mutate({ mutation: ` mutation LogUserCreation($userId: ID!) { logUserCreation(userId: $userId) { id success } } `, variables: { userId }, context, }); } catch (error) { // 捕获后续请求错误,避免影响原始响应 console.error('后续变更请求执行失败:', error); } } } return body; } }
方案二:网关层面的统一处理(可选)
如果需要对所有Mutation请求统一添加后续操作,也可以在Apollo Server的formatResponse钩子中实现,但需要注意网关的响应流程,确保不会阻塞原始响应的返回:
const server = new ApolloServer({ gateway: new ApolloGateway({ // 网关配置 }), formatResponse: async (response, requestContext) => { const isMutation = requestContext.operation?.operation === 'mutation'; const isSuccess = !response.errors; if (isMutation && isSuccess) { // 这里可以调用数据源实例发起后续请求,或者直接发送HTTP请求 const dataSource = requestContext.dataSources?.someRemoteSource; if (dataSource) { // 执行后续变更逻辑 } } return response; }, });
关键注意事项
- 用
try/catch包裹后续请求,避免其错误影响原始请求的响应返回 - 若需要事务性保障,可引入消息队列做兜底处理,避免后续请求失败导致数据不一致
- 要避免循环触发:确保后续执行的Mutation不会再次触发相同的钩子逻辑
内容的提问来源于stack exchange,提问作者Seeker
相关产品推荐
相关产品推荐

