使用 Graphql 和 Amplify/AppSync 基于先前值的突变

Posted

技术标签:

【中文标题】使用 Graphql 和 Amplify/AppSync 基于先前值的突变【英文标题】:Mutation based on previous value with Graphql and Amplify/AppSync 【发布时间】:2021-06-23 13:26:27 【问题描述】:

我想指出我是 Graphql 的新手,我可能遗漏了一些明显的东西。我想做一些类似于商店订单系统的事情。当顾客买东西时,有两件事要做:(1)​​钱从他的钱包里减少,(2)一个订单被添加到他的订单历史中。到目前为止,我在 GraphQL 模式中将钱包和订单历史建模为两种类型。

第 1 点。 理想情况下,我想进行交易。如果钱包更新或订单创建失败,整体应该失败。据我了解,如this answer 中所指出的,要存档此文件,只需一个同时进行更新的突变就足够了。 那么,我是否正确理解了它,并且这样的事情就像一个事务(在失败的情况下回滚)?

mutation 
   update_wallet(...) ...
   add_to_history(...) ...

第 2 点。 其次,我想存储每个客户购买的平均数量。为此,我正在考虑使用增量平均函数 (this one),因此我正在考虑存储当前平均值并使用公式对其进行更新。但是,我不明白如何“安全”地做到这一点(没有可能的竞争条件)。据我了解,GraphQL 中有一个原子增量选项,仅此而已。所以我想我可以存储 sum_of_all_the_items 和 number_of_purchases 以计算每个请求的划分。这可能很好,即使它看起来不是最干净的解决方案。特别是因为这些数字将无限增长并最终(即使这是一个非常不幸的情况)溢出。

谢谢

【问题讨论】:

【参考方案1】:

这是您的 AppSync 背后的数据库的问题。它可能是 DynamoDb 或 RDS。通常,您只需要一个执行客户购买的突变,包括

    从钱包里扣钱 从库存中扣除一些物品 添加/更新订单记录(orderId、userId、numberOfItems、状态) 添加采购记录(orderId、purchaseId、更多采购信息)

所有这些都在一个事务中执行。如果您的数据库是 RDS,那么您可以通过对 Order 表的 SQL 查询轻松计算出平均项目数。数量实时汇总,不存在竞态条件。

另一方面,如果是DynamoDb,this answer里面有很多选项。 DynamoDb 中的竞争条件可能是一个不同的问题,我知道的一种解决方案是 conditional update。

对于您的情况,一个突变应该足够了。突变purchaseWithoutOrder 用于无订单购买。

type Mutation 
  purchase(orderId: ID!): PurchaseResult
  purchaseWithoutOrder(input: PurchaseWithoutOrderInput!): PurchaseResult


type PurchaseWithoutOrderInput 
  items: [Item!]!

【讨论】:

Hung Tran,很好的答案。如果您有更多 AWS 知识,请写信给我。也许我有一些工作给你。

以上是关于使用 Graphql 和 Amplify/AppSync 基于先前值的突变的主要内容,如果未能解决你的问题,请参考以下文章

使用 REST 包装 GraphQL 从 NestJS 提供 GraphQL 和 REST API

GraphQL 和 graphql-sequelize-schema-generator

使用 express-graphql 和 HTTP 客户端从 graphql 获取数据

如何使用 graphql 和 mongoose 进行突变

使用 graphql-java-tools 和 graphql-spring-boot-starter 处理错误

使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL