简体   繁体   English

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

[英]Why should I prefer HTTP REST over HTTP RPC JSON-Messaging style in conjunction with CQRS?

Every time I read about how web service should communicate the first thing that comes up is: 每当我读到Web服务应该如何通信时,首先出现的是:

Use REST , because it decouples client and server! 使用REST ,因为它将客户端和服务器分离

I would like to build a web service where each Query and Command is an Http-Endpoint. 我想构建一个Web服务,其中每个QueryCommand都是一个Http-Endpoint。 With REST I would have fewer endpoints, because of its nature of thinking of resources instead of operations (You typically have more operations than resources). 使用REST,我会有更少的端点,因为它考虑资源而不是操作的性质 (通常比资源有更多的操作)。

  • Why do I have a stronger coupling by using RPC over REST ? 为什么使用RPC over REST有更强的耦合?
  • What is the benefit of using REST over RPC Json-Messaging style? 使用REST而非RPC Json-Messaging样式有什么好处?

Additional information: With messaging I mean synchronous messaging ( request / response ) 附加信息:使用消息传递我的意思是同步消息请求 / 响应

Update: I think it would be also possible/better to only have one single Http endpoint that can handle a Query or Command depending on the given Http verb. 更新:我认为根据给定的Http动词,只有一个Http端点可以处理QueryCommand也是可能/更好的。

Before I get to the CQRS part, I'd like to spend a little time talking about the advantages and disadvantages of REST. 在我进入CQRS部分之前,我想花点时间谈谈REST的优缺点。 I don't think it's possible to answer the question before we've established a common understanding of when and why to use REST. 在我们就何时以及为何使用REST建立共识之前,我认为不可能回答这个问题。

REST 休息

As with most other technology options, REST, too, isn't a silver bullet. 与大多数其他技术选项一样,REST也不是灵丹妙药。 It comes with advantages and disadvantages. 它有优点和缺点。

I like to use Richardson's Maturity Model, with Martin Fowler's additional level 0 , as a thinking tool. 我喜欢使用Richardson的成熟度模型,将Martin Fowler的额外0级作为一种思维工具。

Level 0 0级

Martin Fowler also calls level 0 the swamp of POX , but I think that what really distinguishes this level is simply the use of RPC over HTTP. Martin Fowler也将POX的沼泽称为0级,但我认为真正区分这个级别的只是使用RPC over HTTP。 It doesn't have to be XML; 它不一定是XML; it could be JSON instead. 它可能是JSON而不是。

The primary advantage at this level is interoperability. 这一级别的主要优势是互操作性。 Most system can communicate via HTTP, and most programming platforms can handle XML or JSON. 大多数系统可以通过HTTP进行通信,大多数编程平台都可以处理XML或JSON。

The disadvantage is that systems are difficult to evolve independently of clients (see level 3). 缺点是系统很难独立于客户而发展(见第3级)。

One of the distinguishing traits of this style is that all communication goes through a single endpoint. 这种风格的一个显着特征是所有通信都通过一个端点。

Level 1 1级

At level 1, you start to treat various parts of your API as separate resources. 在级别1,您开始将API的各个部分视为单独的资源。 Each resource is identified by a URL. 每个资源都由URL标识。

One advantage is that you can now start to use off-the-shelf software, such as firewalls and proxy servers, to control access to various distinct parts of the system. 一个优点是您现在可以开始使用现成的软件(例如防火墙和代理服务器)来控制对系统各个不同部分的访问。 You can also use HTTP redirects to point clients to different endpoints, although there are some pitfalls in that regard. 您也可以使用HTTP重定向将客户端指向不同的端点,尽管在这方面存在一些缺陷。

I can't think of any disadvantages , apart from those of level 0. 除了0级之外,我想不出任何缺点

Level 2 2级

At this level, not only do you have resources, but you also use HTTP verbs, such as GET , POST , DELETE , etc. 在这个级别,您不仅拥有资源,还使用HTTP谓词,例如GETPOSTDELETE等。

One advantage is that you can now begin to take more advantage of HTTP infrastructure. 一个优点是您现在可以开始更多地利用HTTP基础结构。 For instance, you can instruct clients to cache responses to GET requests, whereas other requests typically aren't cacheable. 例如,您可以指示客户端缓存对GET请求的响应,而其他请求通常不可缓存。 Again, you can use standard HTTP firewalls and proxies to implement caching. 同样,您可以使用标准HTTP防火墙和代理来实现缓存。 You can get 'web-scale' caching for free. 您可以免费获得“网络规模”缓存。

The reason that level 2 builds on level 1 is that you need each resource to be separate, because you want to be able to cache resources independently from each other. 级别2构建在级别1上的原因是您需要将每个资源分开,因为您希望能够彼此独立地缓存资源。 You can't do this if you can't distinguish various resources from each other, or if you can't distinguish reads from writes. 如果您无法区分各种资源,或者无法区分读取和写入,则无法执行此操作。

The disadvantage is that it may involve more programming work to implement this. 缺点是它可能涉及更多的编程工作来实现它。 Also, all the previous disadvantages still apply. 此外,所有先前的缺点仍然适用。 Clients are tightly coupled to your published API. 客户端与您发布的API紧密耦合。 If you change your URL structure, clients break. 如果您更改了URL结构,则客户端会中断。 If you change data formats, clients break. 如果更改数据格式,客户端会中断。

Still, many so-called REST APIs are designed and published at this level, so in practice it seems that many organisations find this a good trade-off between advantages and disadvantages. 尽管如此,许多所谓的REST API都是在这个级别设计和发布的,所以在实践中似乎很多组织都认为这是优点和缺点之间的良好平衡。

Level 3 3级

This is the level of REST design that I consider true REST. 这是REST设计的级别,我认为是真正的REST。 It's nothing like the previous levels; 它与以前的水平完全不同; it's a completely different way to design APIs. 这是设计API的完全不同的方式。 In my mind, there's a hard divide between levels 0-2, and level 3. 在我看来,0-2级和3级之间存在严重分歧。

One distinguishing feature of level 3 is that you must think content negotiation into the API design . 第3级的一个显着特征是必须将内容协商视为API设计 Once you have that, though, the reasons to choose this API design style become clearer. 但是,一旦你有了这个,那么选择这种API设计风格的理由就会变得更加清晰。

To me, the dominant advantage of level 3 APIs is that you can evolve them independently of clients. 对我而言,3级API的主要优势在于您可以独立于客户进化它们。 If you're careful, you can change the structure, even the navigation graph, of your API without breaking existing clients. 如果您小心,可以在不破坏现有客户端的情况下更改API的结构,甚至导航图。 If you need to introduce breaking changes, you can use content negotiation to ensure that clients can opt-in to the breaking change, whereas legacy clients will keep working. 如果您需要引入重大更改,您可以使用内容协商来确保客户端可以选择进行重大更改,而旧版客户端将继续工作。

Basically, when I'm asked to write an API where I have no control over clients, my default choice is level 3. 基本上,当我被要求编写一个我无法控制客户端的API时,我的默认选择是3级。

Designing a level 3 REST API requires you to design in a way that's unusual and alien to many, so that's a disadvantage . 设计一个3级REST API需要你以一种与众不同的方式进行设计,这是一个缺点 Another disadvantage is that client developers often find this style of API design unfamiliar, so they often try to second-guess, or retro-engineer, your URL structure . 另一个缺点是客户端开发人员经常发现这种API设计风格不熟悉,因此他们经常尝试对您的URL结构进行二次猜测或重新设计 If they do, you'll have to expend some effort to prevent them from doing that as well, since this will prevent you from being able to evolve the API. 如果他们这样做,你将不得不花费一些努力来阻止他们这样做,因为这将阻止你进化API。

In other words, level 3 APIs require considerable development effort, particularly on the server-side, but clients also become more complex. 换句话说,3级API需要大量的开发工作,特别是在服务器端,但客户端也变得更加复杂。

I will, though, reiterate the advantage: you can evolve an level 3 REST API independently of clients. 但是,我将重申优势:您可以独立于客户端发展3级REST API。 If you don't control clients, backwards compatibility is critical. 如果您不控制客户端,则向后兼容性至关重要。 Level 3 enables you to evolve APIs while still retaining compatibility. 级别3使您可以在保持兼容性的同时发展API。 I'm not aware of a way you can achieve this with any of the other styles. 我不知道你可以用任何其他风格来实现这一点。

CQRS CQRS

Now that we've identified some advantages and disadvantages of REST, we can start to discuss whether it's applicable to CQRS. 现在我们已经确定了REST的一些优点和缺点,我们可以开始讨论它是否适用于CQRS。

The most fundamental agreement between Greg Young and Udi Dahan concerning CQRS is that it's not a top-level architecture . Greg Young与Udi Dahan就CQRS达成的最基本协议是, 它不是顶级架构

In a nutshell, the reason for this is that the messages (commands and events) and queries that make up a CQRS system are sensitive to interpretation. 简而言之,其原因在于构成CQRS系统的消息(命令和事件)和查询对解释很敏感。 In order to do something, a client must know which command to issue, and the server must know how to interpret it. 为了一些事情,一个客户端必须知道哪个命令发出,服务器必须知道如何解释它。 The command, thus, is part of the system. 因此,该命令是系统的一部分。

The system may be distributed across clients and servers, but the messages and data structures are coupled to each other. 系统可以跨客户端和服务器分布,但是消息和数据结构彼此耦合。 If you change how your server interprets a given message, that change will impact your clients. 如果您更改服务器解释给定邮件的方式,则该更改将影响您的客户。 You can't evolve clients and servers independently in a CQRS architecture, which is the reason why it's not a top-level architecture. 您无法在CQRS架构中独立地发展客户端和服务器,这也是它不是顶级架构的原因。

So, given that it's not a top-level architecture, the transport architecture becomes fairly irrelevant. 因此,鉴于它不是顶级架构,传输架构变得相当无关紧要。 In a sense, the only thing you need in order to send messages is a single 'service bus' endpoint, which could easily be a level 0 endpoint, if all you need is interoperability. 从某种意义上说,发送消息所需的唯一内容是单个“服务总线”端点,如果您只需要互操作性,则可以很容易地成为0级端点。 After all, the only thing you do is to put a message on a queue. 毕竟,你唯一要做的就是在队列中放一条消息。

The final answer, then, is, as always: it depends. 那么,最终的答案是,一如既往: 它取决于。

Is speed of delivery the most important criterion? 交货速度是最重要的标准吗? And can you control all clients and servers at the same time? 您可以同时控制所有客户端和服务器吗? Then, perhaps level 0 is all you need. 那么,也许你只需要0级。 Perhaps level 2 is fine. 也许2级很好。

On the other hand, if you have clients out of your control (mobile apps, hardware (IoT), business partners using your public API, etc.), you must consider how to deal with backwards and forwards compatibility, in which case level 3 is (IMO) required. 另一方面,如果您的客户无法控制(移动应用程序,硬件(IoT),使用您的公共API的业务合作伙伴等),您必须考虑如何处理向后兼容性,在这种情况下,级别3是(IMO)需要的。 In that case, though, I'd suggest keeping CQRS an implementation detail. 但是,在这种情况下,我建议保留CQRS的实现细节。

The best answer would probably be "it depends", but one of the big things about real REST is that it is stateless. 最好的答案可能是“它取决于”,但真正的REST的一个重要原因是它是无状态的。 And it being stateless means all sorts of things. 无国籍意味着各种各样的事情。

Basically, if you look at the HATEOAS constraint you have the reason for the decoupling 1 基本上,如果你看一下HATEOAS约束,你就有了解耦的原因1

I think that RPC-JSON is not statefull per se, but it definately is not defined as stateless. 认为 RPC-JSON本身并不是有状态的,但它肯定没有被定义为无状态。 So there you have the strongest argument of why the decoupling is very high with REST. 所以你有一个最强烈的论据,为什么与REST的解耦非常高。

1: https://en.wikipedia.org/wiki/HATEOAS , http://restfulapi.net/hateoas/ 1: https//en.wikipedia.org/wiki/HATEOAS,http ://restfulapi.net/hateoas/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM