Rest API和DDD

在我的项目中使用DDD方法

该项目有聚合(实体)交易。这个聚合有很多用例。

对于这个聚合,我需要创建一个rest api。

用标准:创建和删除没问题。

1)CreateDealUseCase(名称,价格和许多其他参数);

POST /rest/{version}/deals/
{ 
   'name': 'deal123','price': 1234;
   'etc': 'etc'
}

2)DeleteDealUseCase(id)

DELETE /rest/{version}/deals/{id}

但是如何处理其他用例呢?

> HoldDealUseCase(id,reason);
> UnholdDealUseCase(id);
> CompleteDealUseCase(id和许多其他参数);
> CancelDealUseCase(id,amercement,reason);
> ChangePriceUseCase(id,newPrice,reason);
> ChangeCompletionDateUseCase(id,newDate,amercement,whyChanged);
>等(共20个用例)……

有什么解决方案?

1)使用动词:

PUT /rest/{version}/deals/{id}/hold
{ 
   'reason': 'test'
}

但!动词不能在url中使用(在REST理论中)。

2)使用完成状态(将在用例之后):

PUT /rest/{version}/deals/{id}/holded
{ 
   'reason': 'test'
}

就个人而言,它看起来很难看。也许我错了?

3)对所有操作使用1 PUT请求:

PUT /rest/{version}/deals/{id}
{ 
   'action': 'HoldDeal','params': {'reason': 'test'}
}

PUT /rest/{version}/deals/{id}
{ 
   'action': 'UnholdDeal','params': {}
}

在后端很难处理。
而且,很难记录。由于1个动作具有许多不同的请求变体,因此已经依赖于特定的响应。

所有解决方案都有明显的缺点。

我在网上看过很多关于REST的文章。到处都只有一个理论,如何与我的具体问题在一起?

I have read many articles about the REST on the internet.

根据我在这里看到的内容,你真的需要至少观看Jim Webber关于REST和DDD的谈话

> Rest in Practice
> Domain Driven Design for RESTful Systems

But what to do with the rest of the use cases?

暂时忽略API – 你将如何使用HTML表单?

你可能有一个网页,呈现交易的代表,上面有一堆链接一个链接会将您带到HoldDeal表单,另一个链接会将您带到ChangePrice表单,依此类推。这些表单中的每一个都将填充零个或多个字段,并且每个表单都会发布到某个资源以更新域模型。

他们都会发布到相同的资源吗?也许,也许不是。它们都具有相同的媒体类型,因此如果它们都发布到同一个Web端点,则必须解码另一侧的内容

鉴于这种方法,您如何实现您的系统?嗯,根据你的例子,媒体类型想成为json,但其余部分确实没有任何问题。

1) Use verbs:

没关系。

But! Verbs can not be used in the url(in REST theory).

不。 REST不关心资源标识符的拼写。有一堆URI最佳实践声称动词是坏的 – 这是真的 – 但这不是来自REST的东西。

但是如果人们如此挑剔,你可以命名命令的端点而不是动词。 (即:“hold”不是动词,它是一个用例)。

Use 1 PUT request for all operations:

老实说,那个也不错。您不希望共享uri(因为指定了PUT方法),但使用模板,客户端可以在其中指定唯一标识符。

这是肉:你正在HTTP和HTTP动词之上构建一个api。 HTTP专为文档传输而设计。客户端为您提供一个文档,描述您的域模型中所请求的更改,并将更改应用于域(或不是),并返回描述新状态的另一个文档。

暂时借用CQRS词汇表,您将发布更新域模型的命令。

PUT /commands/{commandId}
{ 
   'deal' : dealId
   'action': 'HoldDeal','params': {'reason': 'test'}
}

理由 – 您将特定命令(具有特定Id的命令)放入命令队列(这是一个集合)。

PUT /rest/{version}/deals/{dealId}/commands/{commandId}
{ 
   'action': 'HoldDeal','params': {'reason': 'test'}
}

是的,那也没关系。

再看一下RESTBucks。这是一个咖啡店协议,但所有api只是通过小文件来推进状态机。

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...