我的问题是如何根据前端响应数据
查询?
只要您拥有查询中字段的解析器,GraphQL 就会为您开箱即用地执行此操作。根据你的底层数据源查看appropriate resolver。
我如何知道前端想要在响应中显示哪些字段?
这是前端决定的,它可以根据它感兴趣的字段发送不同的查询。下面举几个例子。
如果前端只对一个字段感兴趣,即refundAmount,那么它会发送类似这样的查询。
query {
orders (userId: "someUserId") {
refundAmount
}
}
如果它对多个字段感兴趣,比如 price 和 refundAmount,那么查询将是这样的
query {
orders (userId: "someUserId") {
price,
refundAmount
}
}
更新:过滤响应:
现在,根据更新后的问题,您需要增强解析器以执行此额外过滤。
- 解析器可以始终执行此过滤(类似于refundAmount > 0 的硬编码)
- 支持查询模型
query orders (userId: ID!, OrderFilterInput) [Order] 中的过滤条件,并定义您想要过滤的条件。然后在解析器中支持这些过滤条件来查询底层数据源。还要从客户端获取过滤条件。
在this 示例中查看ModelPostFilterInput 生成的模型。
编辑 2:为过滤器添加更改的架构
假设您更改了架构以支持过滤,并且没有额外的 VTL 请求/响应映射器并且您直接与 Lambda 对话。
这就是 Schema 的样子(当然你会有你的突变和订阅,这里省略了。)
input IntFilterInput { # This is all the kind of filtering you want to support for Int data types
ne: Int
eq: Int
le: Int
lt: Int
ge: Int
gt: Int
}
type Order {
id: ID!
price: Int
refundAmount: Int
period: String!
}
input OrderFilterInput { # This only supports filter by refundAmount. You can add more filters if you need them.
refundAmount: IntFilterInput
}
type Query {
orders(userId: ID!, filter: OrderFilterInput): [Order] # Here you add an optional filter input
}
schema {
query: Query
}
假设您在查询 orders 处附加了 Lambda 解析程序。
在这种情况下,Lambda 需要返回一个订单数组/列表。
如果您进一步将此查询发送到某个表/api,则需要了解过滤器,并为下游系统创建适当的查询或 api 调用。
我展示了一个带有硬编码响应的简单 Lambda。如果我们引入过滤器,这就是变化。
const getFilterFunction = (operator, key, value) => {
switch (operator) {
case "ne":
return x => x[key] != value
case "eq":
return x => x[key] == value
case "le":
return x => x[key] <= value
case "lt":
return x => x[key] < value
case "ge":
return x => x[key] >= value
case "gt":
return x => x[key] > value
default:
throw Error("Unsupported filter operation");
}
}
exports.handler = async(event) => {
let response = [{
"id": "xxx1",
"refundAmount": 10,
"period": '2021-01-01'
}, {
"id": "xxx2",
"refundAmount": 0,
"period": '2021-01-03'
}]
const filter = event.arguments.filter;
if (filter) { // If possible send the filter to your downstream system rather handling in the Lambda
if (filter.refundAmount) {
const refundAmountFilters = Object.keys(filter.refundAmount)
.map(operator => getFilterFunction(operator + "", "refundAmount", filter.refundAmount[operator]));
refundAmountFilters.forEach(filterFunction => { response = response.filter(filterFunction) });
}
}
return response; // You don't have to return individual fields the query asks for. It is taken care by AppSync. Just return a list of orders.
};
有了以上内容,您可以发送各种查询,例如
query MyQuery {
orders(userId: "1") { #without any filters
id
refundAmount
}
}
query MyQuery {
orders(userId: "1", filter: {refundAmount: {ne: 0}}) { # The filter you are interested
id
refundAmount
}
}
query MyQuery {
orders(userId: "1", filter: {refundAmount: {ne: 0, gt: 5}}) { # Mix and Match filters
id
refundAmount
}
}
您不必支持所有运算符进行过滤,您可以只关注ne 或!= 并进一步简化事情。查看this 博客以获取更简单的版本,其中假设了过滤器操作。
最后,在不修改架构的情况下进行过滤的另一种可能性是仅更改您的 Lambda,以确保它返回一组过滤后的结果,要么自己进行过滤,要么向底层系统发送适当的查询/请求以进行过滤。