在DDD领域,我喜欢避免getter和setter完全封装组件的想法,因此唯一允许的交互是通过行为构建的交互.将此与事件采购相结合,我可以获得有关已采取行动以及何时使用组件的良好历史记录.
我一直在考虑的一件事是,我想创建一个到底层服务的宁静网关.出于示例的目的,假设我有一个具有以下方法的Task对象,
ChangeDueDate(DateTime date)
ChangeDescription(string description)
AddTags(params string[] tags)
Complete()
现在显然我将在此对象中包含实例变量来控制在调用相关方法时将触发的状态和事件.
回到REST服务,我看到它的方式有3个选项:
制作RPC样式网址,例如 http://127.0.0.1/api/tasks/{taskid}/changeduedate
允许将许多命令发送到单个端点,例如:
网址: http://127.0.0.1/api/tasks/{taskid}/commands
这将接受命令列表,以便我可以在同一请求中发送以下内容:
ChangeDueDate
命令
ChangeDescription
命令
创建一个真正的RESTful动词,我创建域逻辑以从DTO中提取更改,然后转换为所需的相关事件,例如:
网址: http://127.0.0.1/api/tasks/{taskid}
我会使用PUT动词发送任务的DTO表示
一旦收到,我可以通过一个名为UpdateStateFromDto的方法将DTO提供给实际的Task Domain Object
然后,这将分析dto并将匹配的属性与其字段进行比较以查找差异,并且当找到与特定属性的差异时,可能具有需要触发的相关事件.
现在看着这个,我觉得第二种选择看起来是最好的,但我想知道其他人的想法是什么,如果有一种已知的真正的宁静方式来处理这类问题.我知道第二种选择,从TDD的角度来看这将是一次非常好的体验,而且从性能的角度来看,因为我可以将行为的变化组合到单个请求中,同时仍然跟踪变化.
第一个选项肯定是显式的,但如果需要调用许多行为,则会产生多个请求.
第三个选项听起来并不坏,但我意识到需要一些可以考虑不同属性类型,嵌套等的干净实现.
感谢您的帮助,真正让我的头脑陷入分析瘫痪.只是喜欢一些关于其他人认为是选项的最佳方式的建议,或者我是否错过了一个技巧.
我会说选项1.如果您希望您的服务是RESTful,那么选项2不是一个选项,您将是隧道请求.
POST /api/tasks/{taskid}/changeduedate
很容易实现,但你也可以PUT /api/tasks/{taskid}/duedate
.
如果要将多个过程组合成一个过程,则可以创建控制器资源,例如POST /api/tasks/{taskid}/doThisAndThat
,我会根据客户端使用模式执行此操作.
您真的需要提供在一个请求中调用任意数量的"行为"的能力吗?(订单有关系吗?)
如果你想使用选项3,我会使用PATCH /api/tasks/{taskid}
,这样客户端不需要在请求中包含所有成员,只需要包含需要更改的成员.