【问题标题】:Why should I prefer HTTP REST over HTTP RPC JSON-Messaging style in conjunction with CQRS?为什么我更喜欢 HTTP REST 而不是 HTTP RPC JSON-Messaging 风格与 CQRS 结合使用?
【发布时间】:2017-08-09 03:36:00
【问题描述】:

每次我读到 Web 服务应该如何通信的第一件事就是:

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

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

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

附加信息:关于消息传递,我的意思是同步消息传递请求/响应

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

【问题讨论】:

    标签: json rest rpc cqrs


    【解决方案1】:

    在进入 CQRS 部分之前,我想花一点时间谈谈 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 级就是您所需要的。或许2级就可以了。

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

    【讨论】:

      【解决方案2】:

      最好的答案可能是“视情况而定”,但真正的 REST 的一大优点是它是无状态的。无国籍意味着各种各样的事情。

      基本上,如果您查看 HATEOAS 约束,您就有解耦的原因 1

      认为 RPC-JSON 本身不是有状态的,但它肯定没有被定义为无状态。因此,对于为什么 REST 的解耦性非常高,您就有了最有力的论据。

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

      【讨论】:

      • 无国籍是什么意思?
      • 最快的解释来自维基百科,例如:The client–server communication is constrained by no client context being stored on the server between requests. Each request from any client contains all the information necessary to service the request, and session state is held in the client. The session state can be transferred by the server to another service such as a database to maintain a persistent state for a period and allow authentication
      猜你喜欢
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多