AWS AppSync 在解析子资源之前等待 DynamoDB Streams Lambda 函数
AWS AppSync wait for DynamoDB Streams Lambda function before resolving sub-resource
我有类似于以下的 GraphQL 架构。一个 Bravo 中有多个 Alpha,它们每个都相互引用。 (Bravo 可以得到它的 Alpha,Alpha 可以得到它的 Bravo。)
type Alpha {
id: ID!
value: Int!
bravo: Bravo!
}
type Bravo {
value: Int!
alphas: [Alpha!]!
}
input InputAlpha {
value: Int!
}
type Mutation {
putAlpha(alpha: InputAlpha): Alpha!
}
schema {
mutation: Mutation
}
如您所知,这两种类型都有一个值。 Alpha 的值是任意的,但 Bravo 的值是其关联的 Alpha 的总和。出于性能(和成本)原因,Bravo 的值缓存在 DynamoDB table 中,并在更新 Alpha 时修改。
Alphas 使用简单的 AppSync DynamoDB PutItem
解析器进行更新,目的是通过观察 table 的流的 Lambda 函数更新其 Bravo 的值。这在大多数情况下效果很好;我可以给Alpha放随机值,我可以得到他们Bravo的值。
当我尝试在同一个请求中请求 Bravo 的值时出现问题。 (Lambda 函数需要一些时间从流中更新它。)
mutation putAlpha {
putAlpha(alpha: {
value: 10
}) {
id
value
bravo {
value
}
}
}
当然这个 returns bravo
的旧缓存 value
,因为在 Bravo 解析时 Lambda 函数还没有 运行。
是否有任何方法可以等到 DynamoDB 流的 Lambda 函数触发后再解析 bravo
或者使 PutItem
操作同步?
我能想到的唯一选择是使 putAlpha
解析器成为 Lambda 函数而不是简单的解析器,并在其中执行 Bravo 更新逻辑。
这种Lambda不断更新一个缓存值是正常的,还是我做错了?
如果您知道 运行 updateAlpha 时 Bravo 的下一个值应该是什么(例如,您不需要读取其他 Alpha),您可以使用 BatchPutItem 来更新两个 table秒。
如果不是,我认为 AppSync 目前不完全支持此用例。
要使其正常工作,您需要等待 Bravo 记录更新后才能读取它。我认为目前最简单的方法是使用 Lambda 函数。
您可以尝试的其他一些事情(它们有点老套):
- 让 putAlpha 变异解析器在一个循环中旋转指定的时间量,直到流更新 Bravo 记录。
- 在 Alpha.bravo 上添加一个解析器,它在从 table 读取之前在请求映射模板中等待 X 数量。
- 在 Bravo.value 上添加解析器,查询所有 Alpha,对它们的值求和,然后 returns 求和值。这种做法违背了在 Bravo 上存储值的目的。
我认为您不能在解析器中使用睡眠,但可以使用循环:https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html#loops
希望对您有所帮助!
我认为您的客户应该知道 Bravo 的值是在后台计算的。
如果这不是您可以做出的权衡,请考虑将 Bravo 的更新逻辑移至 putAlpha 突变。
(为避免竞争条件,您可以使用 UpdateExpression 的 ADD 操作。)
一种方法是通过您 API 在您的信息流中更新 Bravo 的价值,并在您的客户端中订阅 Bravo 的更新。尽管您需要提供 window、xhr 等
,但可以在 Lambda 中 运行 aws-appsync
其他几种方式:
- 您可以增加 Bravo 在客户端缓存中的值,而不是从 putAlpha 的响应中获取它。
- Bravo 更新后您可以检索它的值。
(它可能会在几秒钟后更新。也许你有办法验证这个 Alpha 是否应用于 Bravo,将上次 Alpha 的更新时间存储到 Bravo 可以工作。)
我有类似于以下的 GraphQL 架构。一个 Bravo 中有多个 Alpha,它们每个都相互引用。 (Bravo 可以得到它的 Alpha,Alpha 可以得到它的 Bravo。)
type Alpha {
id: ID!
value: Int!
bravo: Bravo!
}
type Bravo {
value: Int!
alphas: [Alpha!]!
}
input InputAlpha {
value: Int!
}
type Mutation {
putAlpha(alpha: InputAlpha): Alpha!
}
schema {
mutation: Mutation
}
如您所知,这两种类型都有一个值。 Alpha 的值是任意的,但 Bravo 的值是其关联的 Alpha 的总和。出于性能(和成本)原因,Bravo 的值缓存在 DynamoDB table 中,并在更新 Alpha 时修改。
Alphas 使用简单的 AppSync DynamoDB PutItem
解析器进行更新,目的是通过观察 table 的流的 Lambda 函数更新其 Bravo 的值。这在大多数情况下效果很好;我可以给Alpha放随机值,我可以得到他们Bravo的值。
当我尝试在同一个请求中请求 Bravo 的值时出现问题。 (Lambda 函数需要一些时间从流中更新它。)
mutation putAlpha {
putAlpha(alpha: {
value: 10
}) {
id
value
bravo {
value
}
}
}
当然这个 returns bravo
的旧缓存 value
,因为在 Bravo 解析时 Lambda 函数还没有 运行。
是否有任何方法可以等到 DynamoDB 流的 Lambda 函数触发后再解析 bravo
或者使 PutItem
操作同步?
我能想到的唯一选择是使 putAlpha
解析器成为 Lambda 函数而不是简单的解析器,并在其中执行 Bravo 更新逻辑。
这种Lambda不断更新一个缓存值是正常的,还是我做错了?
如果您知道 运行 updateAlpha 时 Bravo 的下一个值应该是什么(例如,您不需要读取其他 Alpha),您可以使用 BatchPutItem 来更新两个 table秒。
如果不是,我认为 AppSync 目前不完全支持此用例。
要使其正常工作,您需要等待 Bravo 记录更新后才能读取它。我认为目前最简单的方法是使用 Lambda 函数。
您可以尝试的其他一些事情(它们有点老套):
- 让 putAlpha 变异解析器在一个循环中旋转指定的时间量,直到流更新 Bravo 记录。
- 在 Alpha.bravo 上添加一个解析器,它在从 table 读取之前在请求映射模板中等待 X 数量。
- 在 Bravo.value 上添加解析器,查询所有 Alpha,对它们的值求和,然后 returns 求和值。这种做法违背了在 Bravo 上存储值的目的。
我认为您不能在解析器中使用睡眠,但可以使用循环:https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html#loops
希望对您有所帮助!
我认为您的客户应该知道 Bravo 的值是在后台计算的。 如果这不是您可以做出的权衡,请考虑将 Bravo 的更新逻辑移至 putAlpha 突变。 (为避免竞争条件,您可以使用 UpdateExpression 的 ADD 操作。)
一种方法是通过您 API 在您的信息流中更新 Bravo 的价值,并在您的客户端中订阅 Bravo 的更新。尽管您需要提供 window、xhr 等
,但可以在 Lambda 中 运行 aws-appsync其他几种方式:
- 您可以增加 Bravo 在客户端缓存中的值,而不是从 putAlpha 的响应中获取它。
- Bravo 更新后您可以检索它的值。 (它可能会在几秒钟后更新。也许你有办法验证这个 Alpha 是否应用于 Bravo,将上次 Alpha 的更新时间存储到 Bravo 可以工作。)