将 2 个 REST 端点合并到单个 GraphQL 响应
Posted
技术标签:
【中文标题】将 2 个 REST 端点合并到单个 GraphQL 响应【英文标题】:Merging 2 REST endpoints to a single GraphQL response 【发布时间】:2018-04-13 17:03:32 【问题描述】:graphQL 新手,我正在使用以下架构:
type Item
id: String,
valueA: Float,
valueB: Float
type Query
items(ids: [String]!): [Item]
我的 API 可以针对每种类型(A 和 B)的单个请求返回多个项目,但不能同时返回两个项目,即:
类型 A 的 REST 请求:api/a/items?id=[1,2]
回应:
[
"id":1,"value":100,
"id":2,"value":30
]
类型 B 的 REST 请求:api/b/items?id=[1,2]
回应:
[
"id":1,"value":50,
"id":2,"value":20
]
我想将这 2 个 api 端点合并到一个 graphQL 响应中,如下所示:
[
id: "1",
valueA: 100,
valueB: 50
,
id: "2",
valueA: 30,
valueB: 20
]
问:如何编写一个解析器,为每种类型运行 单个 提取(获得多个项目响应)以确保在查询时不会触发不必要的提取缺少类型ie:
items(ids:["1","2"])
id
valueA
上面的例子应该只获取api/a/items?id=[1,2]
,graphQL 响应应该是:
[
id: "1",
valueA: 100
,
id: "2",
valueA: 30
]
【问题讨论】:
【参考方案1】:所以我假设您使用 javascript 作为语言。在这种情况下,您需要的不是使用直接查询,而是使用片段
所以查询会变成
items(ids:["1","2"])
...data
fragment data on Item
id
valueA
接下来在解析器中,我们需要访问这些片段以找到属于片段一部分的字段,然后根据这些字段解析数据。下面是一个简单的nodejs文件,同样
const util = require('util');
var graphql, buildSchema = require('graphql');
var schema = buildSchema(`
type Item
id: String,
valueA: Float,
valueB: Float
type Query
items(ids: [String]!): [Item]
`);
var root = items: (source, args, root) =>
var fields = root.fragments.data.selectionSet.selections.map(f => f.name.value);
var ids = source["ids"];
var data = ids.map(id => return id: id);
if (fields.indexOf("valueA") != -1)
// Query api/a/items?id=[ids]
//append to data;
console.log("calling API A")
data[0]["valueA"] = 0.12;
data[1]["valueA"] = 0.15;
if (fields.indexOf("valueB") != -1)
// Query api/b/items?id=[ids]
//append to data;
console.log("calling API B")
data[0]["valueB"] = 0.10;
data[1]["valueB"] = 0.11;
return data
,
;
graphql(schema, `items(ids:["1","2"])
...data
fragment data on Item
id
valueA
`, root).then((response) =>
console.log(util.inspect(response, showHidden: false, depth: null));
);
如果我们运行它,输出是
calling API A
data:
items: [ id: '1', valueA: 0.12 , id: '2', valueA: 0.15 ]
如果我们将查询更改为
items(ids:["1","2"])
...data
fragment data on Item
id
valueA
valueB
输出是
calling API A
calling API B
data:
items:
[ id: '1', valueA: 0.12, valueB: 0.1 ,
id: '2', valueA: 0.15, valueB: 0.11 ]
因此,这演示了如何避免在不需要 API A/B 的字段时调用它们。完全按照你的要求
【讨论】:
像魅力一样工作:) 另一个案例研究:如果 API 有不同的字段,我们如何解决将 2 个 API 合并到一个通用模式中的问题?以上是关于将 2 个 REST 端点合并到单个 GraphQL 响应的主要内容,如果未能解决你的问题,请参考以下文章