Graphql 如何从apollo链接错误中获取OneError回调中的uri?
我使用apollo链接错误来处理graphql错误。我需要知道onError回调中当前链接的uri。但是,回调的签名如下所示: 函数({operation,response,graphQLErrors,networkError,forward}) 似乎不可能从这些参数中获取uri。我错过了什么吗?或者我是否需要使用其他工具来实现此目的? 事实上,我需要知道uri以便重试(重试以请求另一台服务器) 我按照如下方式配置客户端:Graphql 如何从apollo链接错误中获取OneError回调中的uri?,graphql,graphql-js,Graphql,Graphql Js,我使用apollo链接错误来处理graphql错误。我需要知道onError回调中当前链接的uri。但是,回调的签名如下所示: 函数({operation,response,graphQLErrors,networkError,forward}) 似乎不可能从这些参数中获取uri。我错过了什么吗?或者我是否需要使用其他工具来实现此目的? 事实上,我需要知道uri以便重试(重试以请求另一台服务器) 我按照如下方式配置客户端: var uriList = [uri1, uri2] const cus
var uriList = [uri1, uri2]
const customFetch = (uri, options) => {
const dynamicURI = getOneURIFromURIList()
return fetch(dynamicURI, options);
}
const errorLink = onError(({ networkError, operation, forward }) => {
if (needRetry(networkError)) {
// Here, if I know the URI of the terminating link, I can removed it
// from the uriList, and customFetch will not choose it again.
return forward(operation)
}
})
const link = errorLink.concat(createHttpLink({ fetch: customFetch }))
请求URL不能作为
onError
回调上的参数使用
客户机只包括一个单独的——通常是HttpLink
或BatchHttpLink
。唯一的例外是当我们使用split
函数同时支持WebSocketLink
和另一个终止链接时。所有这些都表明,您的客户端通常会有一个HttpLink
,并且该链接将有一个用于发出请求的URL——即,通常每个客户端只有一个请求URL。除非您使用的是自定义链接或其他非典型设置,否则对于特定的客户端,您应该已经在onError
回调的上下文之外有权访问此URL
编辑:
我建议使用一种更传统的负载平衡方法,而不是尝试在客户端进行负载平衡(例如,使用实际的负载平衡器或使用实现功能)。这样,您的客户机将只有一个URL可用于初始请求或重试,并决定由后端处理用于请求的服务器
也就是说,您应该能够通过利用上下文和split
函数来实现您想要做的事情。像这样的方法应该会奏效:
import { setContext } from 'apollo-link-context'
import { createHttpLink } from 'apollo-link-http'
import { split, from } from 'apollo-link'
const contextLink = setContext(() => ({
// you could return something other than the URI here, like a number
// we just need some value that's unique to each link
targetURI: getOneURIFromURIList()
}))
const optionalHttpLink1 = split(
(operation) => operation.getContext().targetURI === URI_1,
createHttpLink({ uri: URI_1 })
)
const optionalHttpLink2 = split(
(operation) => operation.getContext().targetURI === URI_2,
createHttpLink({ uri: URI_2 })
)
const optionalHttpLink3 = split(
(operation) => operation.getContext().targetURI === URI_3,
createHttpLink({ uri: URI_3 })
)
const errorLink = onError(({ operation }) => {
// call operation.getContext().targetURI to determine the URI used
})
const link = from([
contextLink,
optionalHttpLink1,
optionalHttpLink2,
optionalHttpLink3,
errorLink,
])
您还需要确保删除customFetch选项,以使上述功能正常工作
还要注意,split
将第二个链接作为可选的第三个参数。因此,通过两个参数,您可以指定条件以及在满足条件时要使用的链接。使用三个参数,可以指定条件、满足条件时要使用的链接以及不满足条件时要使用的链接。综上所述,如果您在上面的示例中只使用两个URI,那么您可以只使用一个split
,而不是三个:
const httpLink = split(
(operation) => operation.getContext().targetURI === URI_1,
createHttpLink({ uri: URI_1 }),
createHttpLink({ uri: URI_2 })
)
如果您有2个以上的URI,您将希望每个URI有一个
拆分。共享您的客户端配置,包括链接,将有助于为您的问题提供更具体的答案。如果没有任何示例代码,很难提供比一般答案更多的答案。@DanielRearden感谢您的友好回复。我重新编辑了这个问题。在重新编辑的过程中,我发现customFetch的uri
参数可能就是我想要的。它是重试时对getOneURIFromURIList
的上一次调用的URI吗?我还没有尝试过。不幸的是,在测试之后,我发现customFetch的uri
参数没有改变,它是默认的/graphql
。用一个未经测试但可行的解决方法编辑了我的答案,解决了您的问题。非常感谢,您的答案确实帮助我解决了问题。按照您的指导,我将targetURI放入上下文中(在代码中使用类似contextLink
)。我仍然使用customFetch
(显示在我的代码中),可以从上下文中获取失败的targetURL,并选择一个新的来重试请求。