使用CQRS的RESTful API设计

时间:2019-07-12 19:46:11

标签: rest cqrs

我知道这个Q/A。答案对我的情况没有多大帮助。

我正在设计基于CQRS的RESTful服务,该服务可提供现有帐户的当前信誉。信誉计算最多需要30秒。

由于计算时间长,并且由于我们出于其他原因希望在此上使用CQRS,因此整个过程是在两个(或多个)请求中完成的:

第一个请求

  • 客户端告诉RESTful服务开始对该帐户进行计算。
  • RESTful服务基本上响应“确定”,并让另一个服务开始计算。

后续请求

  • 客户端向RESTful服务请求计算的信誉得分(如果可用)。
  • RESTful服务以信誉分数或仍在计算的注释作为响应。

问题#1

我应该如何构造第一个请求URI?对于帐号12345,应该类似于以下其中之一吗?

PUT /accounts/12345   payload: {}

我担心这种方法,因为我的read PUT应该是幂等的。

另一个选择:

POST /accounts/12345   payload: {}   // ...but shouldn't POST contain the whole entity in the payload?

...或者,也许将实体从帐户更改为命令...

POST /command/reputation-calculation/12345  payload: {}  // ...feels like we're getting off-course here

...还是其他?


问题#2

对于第二个请求,这似乎更简单一些。 URI应该是这样吗?

GET /accounts/12345/reputations

感谢您的建议。谢谢。

3 个答案:

答案 0 :(得分:1)

我可能已经找到了答案。它涉及将CQRS从客户端移到RESTful服务的控制中,可以选择使用它。

对于每个客户请求,URI可以是:

GET /accounts/12345/reputations

收到后,RESTful服务可以检查最近计算的信誉是否可用。如果最近的信誉可用,则RESTful服务将以200 OK状态进行回复,并传递包含信誉的响应有效负载。

如果没有最近的信誉(根据计算服务,该信誉也不在进行中),则RESTful服务将进入CQRS模式。它告诉计算服务开始计算信誉。

然后,无论是启动计算还是发现已在进行计算,它都会向客户端返回一个202 Accepted并带有后续链接。

根据docs,这种202 Accepted响应似乎是这种异步情况。

答案 1 :(得分:0)

  

我应该如何构造第一个请求URI?

URI的拼写无关紧要-机器不太在乎。如果您考虑通用客户端如何缓存文档,则可以选择专门使用target-uri来使缓存中的一种特定资源无效。

使用POST很适合HTTP缓存的工作方式。另外,这就是我们在HTML中的处理方式,因此您知道它具有良好的记录。

因此,如果您执行GET /accounts/12345来查看当前的信誉得分,那么POST /accounts/12345是启动升级过程的一种完全合理的方法。

如果您正在使用超媒体(这是REST约束之一),那么您从POST获得的响应将在其中包含状态监视器的URI。这样URI可以是您想要的任何内容(因为客户端就在您告诉它的地方)。服务器可能希望获得提示,以了解您要询问的更新。因此可能是GET /reputationUpdate/67890

在与帐户相同的层次结构中使用状态监控器可能会有好处,因此GET /accounts/12345/reputationUpdate/67890也可以。

web linking specification一致的拼写通常会使实施客户端或服务器更加容易,因为您可以从现成的可理解模板的库中获取资源。

答案 2 :(得分:0)

REST不适用于面向CQRS命令的系统。因此,如果客户端是面向命令的,则只需使用HTTP作为传输。

或者,客户端可以创建状态为reputation-enquirycalculating的{​​{1}}资源。后端决定是否可以重用最近计算的结果,在这种情况下,状态将立即为ready。资源为ready时提供score