首页 文章

AWS AppSync在解析子资源之前等待DynamoDB Streams Lambda函数

提问于
浏览
0

我有类似于以下的GraphQL架构 . 单个Bravo中有多个Alpha,它们各自具有相互引用 . (一个Bravo可以获得它的Alphas,一个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
}

如您所知,两种类型都有 Value . Alpha的值是任意的,但Bravo的值是其相关Alpha的总和 . 出于性能(和成本)原因,Bravo的值缓存在DynamoDB表中,并在更新Alpha时进行修改 .

使用简单的AppSync DynamoDB PutItem 解析器更新Alpha,其意图是通过观察表的流的Lambda函数更新其Bravo的值 . 这在大多数情况下效果很好;我可以给Alphas随机值,我可以得到他们的Bravo值 .

当我尝试在同一请求中请求Bravo的值时,会发生此问题 . (Lambda函数需要一些时间才能从流中更新它 . )

mutation putAlpha {
  putAlpha(alpha: {
      value: 10
  }) {
    id
    value
    bravo {
      value
    }
  }
}

当然,这将返回 bravo 的旧缓存 value ,因为在解析Bravo时尚未运行Lambda函数 .

有没有办法等到DynamoDB流的Lambda函数在解析 bravo 之前触发,或者可能使 PutItem 操作同步?

我能想到的唯一选择是让 putAlpha 解析器成为Lambda函数而不是简单的解析器,并在那里进行Bravo更新逻辑 .

这种Lambda是否会不断更新缓存值,或者我做错了什么?

2 回答

  • 2

    我认为您的客户应该知道Bravo的 Value 是在后台计算的 . 如果这不是您可以做出的权衡,请考虑将Bravo的更新逻辑移至putAlpha变异 . (为避免竞争条件,您可以使用UpdateExpression的ADD操作 . )

    一种方法是通过您的流中的API更新Bravo的 Value ,并在您的客户端订阅Bravo的更新 . 虽然你需要提供窗口,xhr等,但可以在Lambda中运行aws-appsync .

    其他几种方式:

    • 您可以增加Bravo 's value in client'的缓存,而不是从putAlpha的响应中获取它 .

    • 您可以检索更新的Bravo 's value once it' . (它可能会在几秒钟后更新 . 也许你有办法验证这个Alpha是否应用于Bravo,将最后Alpha的更新时间存储到Bravo可能有效 . )

  • 2

    如果您知道运行updateAlpha时Bravo的下一个值应该是什么(例如,您不需要读取其他Alpha),则可以使用BatchPutItem更新两个表 .

    如果没有,我不相信AppSync现在完全支持这个用例 .

    为了使其工作,您需要等待Bravo记录在阅读之前得到更新 . 我认为目前最简单的方法是使用Lambda函数 .

    你可以尝试的其他一些事情(他们有点hacky):

    • 使putAlpha突变解析器在循环中旋转指定的时间,直到流更新Bravo记录 .

    • 在Alpha.bravo上添加一个解析器,在从表中读取之前等待请求映射模板中的X金额 .

    • 在Bravo.value上添加一个解析器,它查询所有Alpha,汇总它们的值,然后返回求和值 . 这种方式违背了在Bravo上存储 Value 的目的 .

    我不是't think you can use a sleep in the resolver',但你可以使用循环:https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html#loops

    希望这可以帮助!

相关问题