为什么我应该优先选择基于HTTP RPC JSON-Messaging样式的HTTP REST和CQRS?

时间:2017-03-17 14:16:22

标签: json rest rpc cqrs

每当我读到Web服务应该如何通信时,首先出现的是:

  

使用 REST ,因为它解耦客户端和服务器!

我想构建一个Web服务,其中每个QueryCommand都是一个Http-Endpoint。使用 REST 我会有更少的端点,因为它具有考虑资源而不是操作的性质(您通常拥有的操作多于资源)。

  • 为什么通过 RPC 而不是 REST 来实现更强的耦合?
  • 使用 REST 而不是 RPC Json-Messaging 样式有什么好处?

其他信息:使用消息传递我的意思是同步消息请求 / 响应

更新:我认为根据给定的Http动词,只有一个Http端点可以处理QueryCommand也是可能/更好的。

2 个答案:

答案 0 :(得分:6)

在我进入CQRS部分之前,我想花点时间谈谈REST的优缺点。在我们就何时以及为何使用REST达成共识之前,我不认为可以回答这个问题。

REST

与大多数其他技术选项一样,REST也不是一个灵丹妙药。它有优点和缺点。

我喜欢使用Richardson's Maturity Model, with Martin Fowler's additional level 0作为思考工具。

等级0

Martin Fowler也称0级是POX 的沼泽,但我认为真正区分这个级别的只是使用RPC over HTTP。它不一定是XML;它可能是JSON。

此级别的主要优势是互操作性。大多数系统可以通过HTTP进行通信,大多数编程平台都可以处理XML或JSON。

缺点是系统很难独立于客户而发展(见第3级)。

这种风格的一个显着特征是所有通信都通过一个端点。

1级

在第1级,您开始将API的各个部分视为单独的资源。每个资源都由URL标识。

一个优势是您现在可以开始使用现成的软件(例如防火墙和代理服务器)来控制对系统各个不同部分的访问。您也可以使用HTTP重定向将客户端指向不同的端点,尽管在这方面存在一些缺陷。

除了0级以外,我无法想到任何缺点

等级2

在此级别,您不仅拥有资源,还使用HTTP动词,例如GETPOSTDELETE等。

一个优势是您现在可以开始更多地利用HTTP基础架构。例如,您可以指示客户端缓存对GET个请求的响应,而其他请求通常不可缓存。同样,您可以使用标准HTTP防火墙和代理来实现缓存。您可以获得网络规模'免费缓存。

级别2构建在级别1上的原因是您需要将每个资源分开,因为您希望能够彼此独立地缓存资源。如果您无法区分各种资源,或者您无法区分读取和写入,则无法执行此操作。

缺点是它可能涉及更多的编程工作来实现它。此外,所有先前的缺点仍然适用。客户端与您发布的API紧密耦合。如果您更改了URL结构,则客户端会中断。如果您更改数据格式,客户端就会中断。

尽管如此,许多所谓的REST API都是在这个级别设计和发布的,所以在实践中似乎很多组织都认为这是优点和缺点之间的良好平衡。

等级3

这是我认为真正REST的REST设计级别。它与以前的水平完全不同;它是一种完全不同的API设计方式。在我看来,0-2级和3级之间存在分歧。

第3级的一个显着特征是you must think content negotiation into the API design。但是,一旦你有了这个,那么选择这种API设计风格的理由就会变得更加清晰。

对我而言,3级API的主要优势是您可以独立于客户进化它们。如果您需要小心,可以在不破坏现有客户端的情况下更改API的结构,甚至导航图。如果您需要引入重大更改,您可以使用内容协商来确保客户端可以选择进行重大更改,而旧版客户端将继续工作。

基本上,当我要求编写一个我无法控制客户端的API时,我的默认选择是3级。

设计一个3级REST API要求你以一种与许多人不同寻常和陌生的方式进行设计,这样就会出现劣势。另一个缺点是客户端开发人员经常发现这种API设计风格不熟悉,所以they often try to second-guess, or retro-engineer, your URL structure。如果他们这样做了,你就不得不花费一些力气来阻止他们这样做,因为这会阻止你进化API。

换句话说,3级API需要大量的开发工作,特别是在服务器端,但客户端也变得更加复杂。

但是,我会重申优势:您可以独立于客户端发展3级REST API。如果您不控制客户端,则向后兼容性至关重要。级别3使您可以在保持兼容性的同时发展API。我不知道你可以用任何其他风格来实现这一点。

CQRS

现在我们已经确定了REST的一些优点和缺点,我们可以开始讨论它是否适用于CQRS。

Greg Young与Udi Dahan就CQRS达成的最基本协议是it's not a top-level architecture

简而言之,其原因在于构成CQRS系统的消息(命令和事件)和查询对解释很敏感。为了某事,客户端必须知道要发出哪个命令,并且服务器必须知道如何解释它。因此,该命令是系统的一部分。

系统可以分布在客户端和服务器上,但消息和数据结构彼此耦合。如果您更改服务器解释给定邮件的方式,则该更改将影响您的客户。您无法在CQRS架构中独立发展客户端和服务器,这也是它不是顶级架构的原因。

因此,鉴于它不是顶级架构,传输架构变得相当无关紧要。从某种意义上说,发送消息所需要的唯一一件事就是单一的服务总线'端点,如果您只需要互操作性,则可以很容易地成为0级端点。毕竟,你唯一要做的就是在队列中放一条消息。

然后,最终答案一如既往:取决于。

交货速度是最重要的标准吗?您可以同时控制所有客户端和服务器吗?那么,也许你只需要0级。也许第二级很好。

另一方面,如果您的客户无法控制(移动应用,硬件(IoT),使用您的公共API的业务合作伙伴等),您必须考虑如何处理向后和向前兼容性,在这种情况下,级别3是(IMO)所需的。但是,在这种情况下,我建议保留CQRS的实施细节。

答案 1 :(得分:0)

最好的答案可能是“它取决于”,但真正的REST之一就是它是无状态的。无国籍意味着各种各样的事情。

基本上,如果你看一下HATEOAS约束,你有理由去耦 1

认为 RPC-JSON本身并不是有状态的,但它肯定没有被定义为无状态。因此,你有一个最强烈的论据,说明为什么与REST的解耦非常高。

1:https://en.wikipedia.org/wiki/HATEOAShttp://restfulapi.net/hateoas/