每当我读到Web服务应该如何通信时,首先出现的是:
使用 REST ,因为它解耦客户端和服务器!
我想构建一个Web服务,其中每个Query
和Command
都是一个Http-Endpoint。使用 REST 我会有更少的端点,因为它具有考虑资源而不是操作的性质(您通常拥有的操作多于资源)。
其他信息:使用消息传递我的意思是同步消息(请求 / 响应)
更新:我认为根据给定的Http动词,只有一个Http端点可以处理Query
或Command
也是可能/更好的。
答案 0 :(得分:6)
在我进入CQRS部分之前,我想花点时间谈谈REST的优缺点。在我们就何时以及为何使用REST达成共识之前,我不认为可以回答这个问题。
与大多数其他技术选项一样,REST也不是一个灵丹妙药。它有优点和缺点。
我喜欢使用Richardson's Maturity Model, with Martin Fowler's additional level 0作为思考工具。
Martin Fowler也称0级是POX 的沼泽,但我认为真正区分这个级别的只是使用RPC over HTTP。它不一定是XML;它可能是JSON。
此级别的主要优势是互操作性。大多数系统可以通过HTTP进行通信,大多数编程平台都可以处理XML或JSON。
缺点是系统很难独立于客户而发展(见第3级)。
这种风格的一个显着特征是所有通信都通过一个端点。
在第1级,您开始将API的各个部分视为单独的资源。每个资源都由URL标识。
一个优势是您现在可以开始使用现成的软件(例如防火墙和代理服务器)来控制对系统各个不同部分的访问。您也可以使用HTTP重定向将客户端指向不同的端点,尽管在这方面存在一些缺陷。
除了0级以外,我无法想到任何缺点。
在此级别,您不仅拥有资源,还使用HTTP动词,例如GET
,POST
,DELETE
等。
一个优势是您现在可以开始更多地利用HTTP基础架构。例如,您可以指示客户端缓存对GET
个请求的响应,而其他请求通常不可缓存。同样,您可以使用标准HTTP防火墙和代理来实现缓存。您可以获得网络规模'免费缓存。
级别2构建在级别1上的原因是您需要将每个资源分开,因为您希望能够彼此独立地缓存资源。如果您无法区分各种资源,或者您无法区分读取和写入,则无法执行此操作。
缺点是它可能涉及更多的编程工作来实现它。此外,所有先前的缺点仍然适用。客户端与您发布的API紧密耦合。如果您更改了URL结构,则客户端会中断。如果您更改数据格式,客户端就会中断。
尽管如此,许多所谓的REST API都是在这个级别设计和发布的,所以在实践中似乎很多组织都认为这是优点和缺点之间的良好平衡。
这是我认为真正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。我不知道你可以用任何其他风格来实现这一点。现在我们已经确定了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/HATEOAS,http://restfulapi.net/hateoas/