RESTful API 使用 CQRS 进行设计
RESTful API design with CQRS
我知道这个 。答案对我的情况没有多大帮助。
我正在设计一个基于 CQRS 的 RESTful 服务,该服务提供现有帐户的当前信誉。信誉计算最多可能需要 30 秒。
由于计算时间较长,并且由于其他原因我们希望在此上使用CQRS,因此整个过程在两个(或更多)请求中完成:
第一个请求
- 客户告诉 RESTful 服务开始计算帐户。
- RESTful 服务基本上响应 "OK" 并让另一个服务开始计算。
后续请求
- 客户端向 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
感谢您的建议。谢谢。
How should I structure the first request 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 一致的拼写通常使客户端或服务器的实施更容易,因为您可以获取理解模板的现成库。
我可能已经找到答案了。它涉及将 CQRS 从客户端移开,并置于 RESTful 服务的控制之下,该服务可以选择使用它。
对于每个客户端请求,URI 可以是:
GET /accounts/12345/reputations
收到后,RESTful 服务可以检查 recently-calculated 信誉是否可用。如果最近的信誉可用,RESTful 服务会回复 200 OK
状态并传送包含信誉的响应负载。
如果没有最近的信誉可用(根据计算服务也不是 in-process),RESTful 服务将进入 CQRS 模式。它告诉计算服务开始计算信誉。
然后,无论是开始计算,还是发现计算已经在进行中,它都会 returns 向客户端 202 Accepted
和 follow-up link。
根据 docs.
,这种异步情况似乎是 202 Accepted
响应的目的
REST 不太适合 CQRS command-oriented 系统。因此,如果客户端是 command-oriented,则只需使用 HTTP 作为传输方式。
或者,客户端可以创建状态为 calculating
或 ready
的 reputation-enquiry
资源。 back-end 决定是否可以重复使用最近的计算结果,在这种情况下,状态将立即变为 ready
。当资源为 ready
.
时提供 score
我知道这个
我正在设计一个基于 CQRS 的 RESTful 服务,该服务提供现有帐户的当前信誉。信誉计算最多可能需要 30 秒。
由于计算时间较长,并且由于其他原因我们希望在此上使用CQRS,因此整个过程在两个(或更多)请求中完成:
第一个请求
- 客户告诉 RESTful 服务开始计算帐户。
- RESTful 服务基本上响应 "OK" 并让另一个服务开始计算。
后续请求
- 客户端向 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
感谢您的建议。谢谢。
How should I structure the first request 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 一致的拼写通常使客户端或服务器的实施更容易,因为您可以获取理解模板的现成库。
我可能已经找到答案了。它涉及将 CQRS 从客户端移开,并置于 RESTful 服务的控制之下,该服务可以选择使用它。
对于每个客户端请求,URI 可以是:
GET /accounts/12345/reputations
收到后,RESTful 服务可以检查 recently-calculated 信誉是否可用。如果最近的信誉可用,RESTful 服务会回复 200 OK
状态并传送包含信誉的响应负载。
如果没有最近的信誉可用(根据计算服务也不是 in-process),RESTful 服务将进入 CQRS 模式。它告诉计算服务开始计算信誉。
然后,无论是开始计算,还是发现计算已经在进行中,它都会 returns 向客户端 202 Accepted
和 follow-up link。
根据 docs.
,这种异步情况似乎是202 Accepted
响应的目的
REST 不太适合 CQRS command-oriented 系统。因此,如果客户端是 command-oriented,则只需使用 HTTP 作为传输方式。
或者,客户端可以创建状态为 calculating
或 ready
的 reputation-enquiry
资源。 back-end 决定是否可以重复使用最近的计算结果,在这种情况下,状态将立即变为 ready
。当资源为 ready
.
score