我有 graphql 用户类型,需要来自多个 REST api 和不同服务器的信息。 基本示例:从休息域 1 获取用户名字并从休息域 2 获取姓氏。两个休息域都有一个共同的“userID”属性。
我的解析器代码 atm 的简单示例:
user: async (_source, args, { dataSources }) => {
try {
const datasource1 = await dataSources.RESTAPI1.getUser(args.id);
const datasource2 = await dataSources.RESTAPI2.getUser(args.id);
return { ...datasource1, ...datasource2 };
} catch (error) {
console.log("An error occurred.", error);
}
return [];
}
这对于这个简单的版本来说效果很好,但是这个解决方案有两个问题: 首先,IRL 中有很多逻辑用于合并 2 个 json 结果。由于某些字段是共享的但具有不同的数据(或为空)。因此,这就像挑选两个结果来创建一个组合结果。
我的第二个问题是,这仍然是瀑布方法。首先从restapi1获取数据,完成后调用restapi2。基本上 apollo-server 正在重新引入 rest-waterfall-fetch graphql 试图解决的问题。
记住这两个问题..我可以优化这段代码或重写以获得更好的性能或可读性吗?或者是否有任何软件包可以帮助解决此行为?
非常感谢!
最佳答案
关于性能,如果两个调用彼此独立,您可以利用 Promise.all
并行执行它们:
const [dataSource1,dataSource2] = await Promise.all([
dataSources.RESTAPI1.getUser(args.id),
dataSources.RESTAPI2.getUser(args.id),
])
我们通常让 GraphQL 的默认解析器逻辑完成繁重的工作,但如果您发现需要从两个调用中“挑选”数据,则可以在根解析器中返回如下内容:
return { dataSource1, dataSource2 }
然后为每个字段编写解析器:
const resolvers = {
User: {
someField: ({ dataSource1, dataSource2 }) => {
return dataSource1.a || dataSource2.b
},
someOtherField: ({ dataSource1, dataSource2 }) => {
return someCondition ? dataSource1.foo : dataSource2.bar
},
}
}
关于javascript - 组合多个 Rest 调用以填充 apollo-server 中的 1 个 graphQL 类型的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61075960/