CQRS 中的 HTTP REST 响应

本尼迪克特

我正在构建 HTTP REST API 并为 API 实现 CQRS、DDD、ES 和微服务概念。

例如,我想为订购系统构建 API。订单包含订单状态、客户数据、员工数据、购物车项目、运输数据。订单命令服务和订单查询服务使用不同的代码,不同的数据库。和不同的IP/端口。

客户数据包括客户 ID、名字、姓氏、联系电话等。销售和员工等员工数据包括员工 ID、电子邮件、姓名和角色。送货数据包括送货地址、城市、邮政编码、送货单、送货方式和送货费用。购物车项目包含产品 ID 和数量。客户数据、产品数据、员工数据和运输方式数据来自其他服务。

当我想开发它时,我有两个问题。

  1. 当我构建 POST 方法以从销售/员工创建新订单时,请求有效负载中应该包含什么是否可以只发送客户 ID 和员工 ID 作为请求负载?还是应该将客户姓名和联系电话作为有效负载发送?
  2. 当我构建 POST / PUT 方法时,我应该返回响应代码 200 吗?响应中应该包含哪些内容例如,我只在员工创建新订单时将客户 ID 和员工 ID 发送到订单命令服务。响应正文是否应该显示包含其他服务结果的完整订单数据(例如来自客户 ID 的姓名和联系电话等)?不仅如此,非规范化器系统相当慢。需要非规范化器来获取客户和员工的详细信息。这取决于网络延迟和其他服务响应。但是,用户希望立即获得订单数据。

我应该怎么做才能以正确的方式开发 HTTP REST API?

谢谢你。

无理之声

我正在构建 HTTP REST API 并为 API 实现 CQRS、DDD、ES 和微服务概念。

凉爽的。牢记 REST API 部分是集成组件的一部分;其目的是确保老客户可以继续利用您的服务,即使这些服务的实施不断发展。

Jim Webber,RESTful 系统的领域驱动设计

Web 不是您的域,它是一个文档管理系统。所有 HTTP 动词都适用于文档管理域。URI 不映射到域对象 - 这违反了封装。工作(例如:向域模型发出命令)是管理资源的副作用。换句话说,资源是反腐败层的一部分。您应该期望在您的集成域中拥有比在您的业务域中拥有的业务对象更多的资源。

当我构建 POST 方法以从销售/员工创建新订单时,请求有效负载中应该包含什么?

请注意上面关于“更多资源”的观点——您可以提供尽可能多的不同方式(协议)来创建您愿意支持的新订单。

从微服务的角度来看,下单可能涉及到许多不同的业务能力。参见 Udi Dahan 关于UI Composition Techniques的著作,同样的问题也出现在机器对机器的界面中。

因此,从最终与服务通信订单的 Web 端点的角度来看,您需要的信息将取决于公开的端点需要什么。

从客户端的角度来看:提供REST API的部分意义在于集成资源可以引导客户端构建最终提交。想想在线购物体验 - 亚马逊不会要求您输入一堆 SKU 或客户 ID。您只需提交一系列表单,直到出现一个允许您对数据进行最后一次检查的屏幕,然后如果看起来正确,您就提交它。

因此,沿途的屏幕之一可以帮助客户确定员工 ID 应该是什么(这是一个搜索表单,这是一个可供选择的列表等)。

当我构建 POST / PUT 方法时,我应该返回响应代码 200 吗?

一般来说,200就可以了。除非您预计客户会对不同形式的成功做出巧妙的反应,否则这将涵盖您的大多数情况。

202 Accepted是一种更细粒度的状态,通常在处理不会立即完成时使用。“嗨,我们收到了您的订单。这是一个链接,您可以使用它来查看进度。”

例如,如果您使用的架构中 REST api 将简单地将订单请求写入队列以供微服务消费者接收,那么 202 在概念上是准确的“我们写下来,服务将自行决定怎么办”。

用户希望立即获取订单数据。

Instantly不是您可能遇到的延迟,因此您需要一个更宽容的 SLA。

我没想到会出现这种问题;毕竟,如果您的设计是 CQRS,您可以对热缓存中的大量可用数据进行非规范化表示。如果该表示是可独立寻址和可缓存的,则您可以重用存储在客户端上的副本。

但是,后端 API 如何知道用户想要按订单购买该产品?我们收到 SKU 作为有效载荷,不是吗?

不一定——我们会收到 REST API 可以用来计算 SKU 的东西。它可能是别的东西。但是 SKU 很好:从客户端的角度来看,主要的一点是消息格式没有改变;购物者的角度来看,主要的一点是,她不必关心有效载荷中的内容,因为她有稳定的语义线索可以工作(即:她正在查看产品名称,但在封面是 SKU)。

映射 HTTP 动词、URI 和域对象的理想方法是什么?

反过来说:让您的后端服务看起来像一个网站的正确方法是什么?

曾经使用您的网络浏览器配置无线路由器吗?它是如何工作的——路由器内部与网站完全不同。您用来询问堆栈溢出问题的应用程序没有理由应该用作路由器配置工具。然而它确实如此,因为路由器上的 API 知道如何像网站一样躲避,同时向后端发送正确的指令。

REST 客户端只查看它收到的消息;它不知道任何有关域对象; 它只知道资源的表示(想想描述事物的文档)。

映射 HTTP 动词等的理想方式,它伪装成一个愚蠢的文档存储。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何模拟rest API的http响应?

来自分类Dev

在ReST响应中返回JSP

来自分类Dev

在PowerShell中解析ReST响应

来自分类Dev

修改groovy中的REST响应

来自分类Dev

在ReST响应中返回JSP

来自分类Dev

Windows下的Apache Karaf中的HTTP REST响应未完成

来自分类Dev

CQRS实施中每个HTTP请求多个命令

来自分类Dev

Go中的时间HTTP响应

来自分类Dev

Go中的http响应迭代

来自分类Dev

HTTP响应中的意外内容

来自分类Dev

PHP 5.4中的HTTP响应

来自分类Dev

在Ruby中解析http响应

来自分类Dev

HTTP协议中POST请求/响应正文的有效负载的最大限制是多少?通过REST发送JSON

来自分类Dev

如何在Rest api的HTTP方法请求和响应中应用Json序列化或反序列化

来自分类Dev

如何在Rest api的HTTP方法请求和响应中应用Json序列化或反序列化

来自分类Dev

WildFly 10 上的 JAX-RS REST 服务 + EJB,总是在响应中添加无缓存 HTTP 标头

来自分类Dev

github操作中HTTP响应中的空响应主体

来自分类Dev

Spring Rest响应中的异常的Stacktrace

来自分类Dev

在Spring Rest Docs中记录byte []响应

来自分类Dev

如何在Groovy中获得REST响应?

来自分类Dev

REST API中搜索的响应状态代码

来自分类Dev

REST API中对作业结果的适当响应

来自分类Dev

Java Rest Service响应中的XML解析

来自分类Dev

从Spring REST服务接收Android中的响应

来自分类Dev

Spring REST Docs 中的文档图像响应

来自分类Dev

带有REST API的CQRS

来自分类Dev

在Spring Rest Service调用期间根据HTTP代码解组响应

来自分类Dev

REST API最佳HTTP状态响应,用于非法操作

来自分类Dev

Java的:执行HTTP REST GET呼叫而不读取响应