【问题标题】:How to do POST partial updates via REST API and using DDD?如何通过 REST API 和使用 DDD 进行 POST 部分更新?
【发布时间】:2018-03-20 13:34:43
【问题描述】:

我有一个项目,将 rest api 从经典 CRUD 重构为域驱动设计 (DDD)。挑战之一是端点必须使用相同的动词和有效负载保持相同。

我有以下情况

例如 GET /orders/1048 返回

{
   "id":1048,
   "order_total":100.11,
   "is_paid":true,
   "order_status":"active",
   "items":[
      {
         "id":5000,
         "name":"baseball hat"
      },
      {
         "id":5001,
         "name":"baseball bat"
      }
   ]
}

现在,如果我有 POST 订单/更新/1048,我通过 POST 发送全部或部分请求模型(不是通过 PUT,因为 POST 不是幂等的,并且 PUT 请求始终提供整个模型)并基于我想要的数据触发特定的域行为

a) 更新状态案例 1.

{
   "id":1048,
   "order_total":100.11,
   "is_paid":true,
   "order_status":"cancel",
   "items":[
      {
         "id":5000,
         "name":"baseball hat"
      },
      {
         "id":5001,
         "name":"baseball bat"
      }
   ]
}

b) 更新状态案例 2.

{
    "id": 1048,
    "order_status": "cancel"
}

c) 更新项目案例

{
   "id":1048,
   "items":[
      {
         "id":5000,
         "name":"baseball hat"
      }
   ]
}

d) 更新状态 + 项目

{
   "id":1048,
   "order_status":"cancel",
   "items":[
      {
         "id":5000,
         "name":"baseball hat"
      }
   ]
}

我的计划是在应用层和领域层做以下事情。

  • 检索域数据
  • 将现有域数据与请求正文中提供的数据进行比较(开发比较逻辑)
  • 决定触发哪些行为
  • 触发选定的行为
  • 如果行为有效,则保留整个(更新的)域数据

这并不是真正的“DDD 就绪请求”,因为我没有使用 PATCH 发送命令,但这是我能想到的唯一解决方法,我想知道我做得对吗?

【问题讨论】:

  • Rest API and DDD的可能重复
  • “这不是真正的 DDD,因为我没有使用 PATCH 发送命令” - 那是什么时候的 DDD?
  • 发送命令你试图更新什么是更多的 DDD 准备好然后发送必须处理的大量数据并确定要使用的命令。没有?
  • 可能更多的是 CQRS。而且 PATCH 不是先决条件。无论如何,“PATCH 上的命令 DDD” :只是假的。

标签: rest domain-driven-design


【解决方案1】:

考虑到您可能不会不能修改客户端:

我的计划是在应用层和领域层做以下事情

如果你只在应用层这样做,那么只要领域层只包含领域逻辑,它就是 DDD。 diff算法不属于领域层,应该属于临时重构门面;这个门面可以放在更远的地方,在应用层之前,以便在重构完成后更简单地移除。

如果/当你重构客户端时:

您发送到域(发送到聚合)的命令可以使用 POST 或 PUT(取决于命令的幂等性)包装在 RESTful 请求中。对于每个域命令(不是每个域实体),您都可以拥有一个 REST 资源,例如 http://server/place/order/{orderId}

然后你可以放弃重构外观。

【讨论】:

  • 如果您暗示这种重构应该是暂时的,您是否建议有一种通过 REST 更新域的理想方法?
  • @mko 是的,“理想”是一个强词,“更好”更好
  • @mko 不是临时的,而是分两个阶段:后端然后前端
  • @mko 使用 DDD Api 的 CRUD 客户端是应该避免的。客户端也应该是 DDDish
【解决方案2】:

如果内容类型是可变的,您可以使用它们来传达有关命令的信息并在此进行匹配,而不是逐个字段进行比较。

PUT /order/1048
Content-Type:application/json;command=UpdateStatus

https://www.infoq.com/articles/rest-api-on-cqrs

附带说明,UpdateStatus 作为命令名称可能不够具体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多