如何通过REST API和使用DDD进行POST部分更新?

时间:2017-10-09 10:56:50

标签: rest domain-driven-design

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

我有以下情况

例如GET / orders / 1048返回

 var ss = SpreadsheetApp.openById('***');
 var rowCount = ss.getLastRow();


for (i=1; i <= rowCount; i++) {

   var I = ss.getRange("I" + i).getValue(); 
   var J = ss.getRange("J" + i).getValue(); 
   var K = ss.getRange("K" + i).getValue(); 
   var L = ss.getRange("L" + i).getValue(); 
   var M = ss.getRange("M" + i).getValue(); 
   var N = ss.getRange("N" + i).getValue(); 
   var O = ss.getRange("O" + i).getValue(); 
   var P = ss.getRange("P" + i).getValue(); 
   var Q = ss.getRange("Q" + i).getValue(); 
   var R = ss.getRange("R" + i).getValue(); 
   var S = ss.getRange("S" + i).getValue(); 
   var T = ss.getRange("T" + i).getValue();
  if(I === 0 && J === 0 && K === 0 && L === 0 && M === 0 && N === 0 && O === 0 && P === 0 && Q === 0 && R === 0 && S === 0 && T === 0){

    Logger.log(ss.getRange("I" + i).getA1Notation());

    ss.deleteRow(i);

  }


} 

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

a)更新状态案例1.

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

b)更新状态案例2.

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

c)更新项目案例

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

d)更新状态+项目

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

我的计划是在应用层和域层内执行以下操作。

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

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

2 个答案:

答案 0 :(得分:2)

考虑到您可能无法修改客户端:

  

我的计划是在应用层和域层内执行以下操作

如果仅在Application层中执行此操作,则只要域层仅包含域逻辑,它就是DDD。 diff算法不属于域层,它应该属于临时重构外观;这个外观可以放在Application层前面,以便在重构完成后更简单地删除。

如果/当你重构客户时:

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

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

答案 1 :(得分:2)

如果内容类型可更改,您可以使用它们来传达有关命令的信息,并通过字段比较来传达该信息而不是字段。

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

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

作为旁注,UpdateStatus可能不够具体作为命令名。