CQRS 中的 HTTP REST 响应
HTTP REST Response in CQRS
我正在构建 HTTP REST API 并为 API 实施 CQRS、DDD、ES 和微服务概念。
例如,我想构建API用于订购系统。订单包含订单状态、客户数据、员工数据、购物车项目、运输数据。订单命令服务和订单查询服务使用不同的代码,不同的数据库。和不同的 ip / 端口。
客户数据包括客户 ID、名字、姓氏、联系电话等。销售和员工等员工数据包括员工 ID、电子邮件、姓名和角色。送货数据包括送货地址、城市、邮政编码、送货单、送货方式和送货成本。购物车项目包含产品 ID 和数量。客户数据、产品数据、员工数据和运输方式数据是从其他服务中产生的。
开发的时候有两个问题
- 当我构建 POST 方法以从销售人员/员工创建新订单时,请求 负载中应该包含什么?是否可以只发送客户 ID 和员工 ID 作为请求负载?或者我应该将客户姓名和联系电话作为负载发送吗?
- 当我构建 POST / PUT 方法时,我应该 return 响应代码 200 吗? 响应中应该包含什么?例如,当员工向订单命令服务创建新订单时,我只发送客户 ID 和员工 ID。响应正文是否应显示包含其他服务结果的完整订单数据(如客户 ID 中的姓名和联系电话等)?不仅如此,去规范器系统相当慢。需要反规范化器来获取客户和员工的详细信息。这取决于网络延迟和其他服务响应。但是,用户想要即时获取订单数据。
如何正确开发HTTP RESTAPI?
谢谢。
I am building HTTP REST API and implementing CQRS, DDD, ES, and microservices concept for the API.
酷。请牢记 REST API 部分是集成组件的一部分;其目的是确保老客户可以继续利用您的服务,即使这些服务的实施不断发展。
吉姆韦伯,Domain-Driven Design for RESTful Systems
The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources. In other words, the resources are part of the anti-corruption layer. You should expect to have many many more resources in your integration domain than you do business objects in your business domain.
When I build the POST method to create new order from sales / staff, what should be in a request payload?
请注意上面关于“更多资源”的观点——您可以提供尽可能多的不同方式(协议)来创建您愿意支持的新订单。
从微服务的角度来看,下单可能涉及到很多不同的业务能力。请参阅 Udi Dahan 关于 UI Composition Techniques 的文章,同样的问题也出现在机器对机器的接口中。
因此,从最终与服务通信订单的 Web 端点的角度来看,您需要的信息将取决于公开的端点需要什么。
从客户端的角度来看:提供REST的部分观点API是整合资源可以引导客户端构建最终的提交。想想在线购物体验——亚马逊不会要求您输入一堆 SKU 或客户 ID。您只需提交一系列表格,直到您到达一个屏幕,让您对数据进行最后一次检查,然后如果看起来正确就提交它。
所以其中一个屏幕可能会帮助客户弄清楚员工 ID 应该是什么(这是一个搜索表单,这是一个可供选择的列表,等等)。
When I build the POST / PUT method, should I return response code 200?
一般来说200就可以了。除非您预计客户会对不同形式的成功作出巧妙反应,否则这将涵盖您的大部分案例。
202 Accepted 是一种更细粒度的状态,通常在处理不会立即完成时使用。 “您好,我们收到了您的订单。这是一个 link,您可以用来检查进度。”
例如,如果您使用的架构中 REST api 只是将订单请求写入队列以供微服务消费者提取,那么 202 在概念上是准确的“我们写了它下来,服务将自行决定如何处理。
user want to get the order data instantly.
即时 不是您可能遇到的延迟,因此您需要一个更宽容的 SLA。
我没想到会有这样的问题;毕竟,如果您的设计是 CQRS,您可以对热缓存中的大量可用数据进行非规范化表示。如果该表示是可独立寻址和缓存的,则您可以重新使用存储在客户端上的副本。
But, how the backend API know that user wants to buy that product to an order? We receive the SKU as payload, don't we?
不一定——我们收到 REST API 可以用来计算 SKU 的东西。它可能是别的东西。但是 SKU 很好:从客户的角度来看,主要的一点是消息格式没有改变; 购物者的主要观点是她不必关心有效负载中的内容,因为她有稳定的语义线索可以工作(即:她正在看产品名称,但在封面下提交的表格是 SKU)。
What is the ideal way to map the HTTP verbs, URI, and domain objects?
换句话说:使后端服务看起来像网站的正确方法是什么?
曾经使用网络浏览器配置无线路由器吗?它是如何工作的——路由器的内部结构与网站完全不同。您用来询问堆栈溢出问题的应用程序没有理由用作路由器配置工具。然而它确实如此,因为路由器上的 API 知道如何像网站一样躲避,同时向后端发送正确的指令。
REST 客户端只查看它收到的消息;它对领域对象一无所知;它只知道资源的表示(想想描述事物的文档)。
映射 HTTP 动词等的理想方式,它伪装成一个愚蠢的文档存储。
这是一个迟到的响应,但它可能对正在寻找如何通过 HTTP 实现 CQRS 体系结构模式的人有所帮助。
在我的发现过程中,我决定分享我的发现并最终写了一系列关于如何通过 HTTP 执行 CQRS 的文章。
我特别想指出 RESTful 架构在概念上不同于 CQRS,因此不太适合某个目的。我试图在通过 HTTP 命令一文中对两种架构进行详尽的比较。
除了理论方面,在写作过程中,我设法构建了两个随时可用的独立中间件,旨在帮助您在 ASP NET Core 项目中采用 CQRS。 HTTP Commanding and HTTP Querying.
希望对你有帮助,有什么问题可以给我留言。
我正在构建 HTTP REST API 并为 API 实施 CQRS、DDD、ES 和微服务概念。
例如,我想构建API用于订购系统。订单包含订单状态、客户数据、员工数据、购物车项目、运输数据。订单命令服务和订单查询服务使用不同的代码,不同的数据库。和不同的 ip / 端口。
客户数据包括客户 ID、名字、姓氏、联系电话等。销售和员工等员工数据包括员工 ID、电子邮件、姓名和角色。送货数据包括送货地址、城市、邮政编码、送货单、送货方式和送货成本。购物车项目包含产品 ID 和数量。客户数据、产品数据、员工数据和运输方式数据是从其他服务中产生的。
开发的时候有两个问题
- 当我构建 POST 方法以从销售人员/员工创建新订单时,请求 负载中应该包含什么?是否可以只发送客户 ID 和员工 ID 作为请求负载?或者我应该将客户姓名和联系电话作为负载发送吗?
- 当我构建 POST / PUT 方法时,我应该 return 响应代码 200 吗? 响应中应该包含什么?例如,当员工向订单命令服务创建新订单时,我只发送客户 ID 和员工 ID。响应正文是否应显示包含其他服务结果的完整订单数据(如客户 ID 中的姓名和联系电话等)?不仅如此,去规范器系统相当慢。需要反规范化器来获取客户和员工的详细信息。这取决于网络延迟和其他服务响应。但是,用户想要即时获取订单数据。
如何正确开发HTTP RESTAPI?
谢谢。
I am building HTTP REST API and implementing CQRS, DDD, ES, and microservices concept for the API.
酷。请牢记 REST API 部分是集成组件的一部分;其目的是确保老客户可以继续利用您的服务,即使这些服务的实施不断发展。
吉姆韦伯,Domain-Driven Design for RESTful Systems
The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources. In other words, the resources are part of the anti-corruption layer. You should expect to have many many more resources in your integration domain than you do business objects in your business domain.
When I build the POST method to create new order from sales / staff, what should be in a request payload?
请注意上面关于“更多资源”的观点——您可以提供尽可能多的不同方式(协议)来创建您愿意支持的新订单。
从微服务的角度来看,下单可能涉及到很多不同的业务能力。请参阅 Udi Dahan 关于 UI Composition Techniques 的文章,同样的问题也出现在机器对机器的接口中。
因此,从最终与服务通信订单的 Web 端点的角度来看,您需要的信息将取决于公开的端点需要什么。
从客户端的角度来看:提供REST的部分观点API是整合资源可以引导客户端构建最终的提交。想想在线购物体验——亚马逊不会要求您输入一堆 SKU 或客户 ID。您只需提交一系列表格,直到您到达一个屏幕,让您对数据进行最后一次检查,然后如果看起来正确就提交它。
所以其中一个屏幕可能会帮助客户弄清楚员工 ID 应该是什么(这是一个搜索表单,这是一个可供选择的列表,等等)。
When I build the POST / PUT method, should I return response code 200?
一般来说200就可以了。除非您预计客户会对不同形式的成功作出巧妙反应,否则这将涵盖您的大部分案例。
202 Accepted 是一种更细粒度的状态,通常在处理不会立即完成时使用。 “您好,我们收到了您的订单。这是一个 link,您可以用来检查进度。”
例如,如果您使用的架构中 REST api 只是将订单请求写入队列以供微服务消费者提取,那么 202 在概念上是准确的“我们写了它下来,服务将自行决定如何处理。
user want to get the order data instantly.
即时 不是您可能遇到的延迟,因此您需要一个更宽容的 SLA。
我没想到会有这样的问题;毕竟,如果您的设计是 CQRS,您可以对热缓存中的大量可用数据进行非规范化表示。如果该表示是可独立寻址和缓存的,则您可以重新使用存储在客户端上的副本。
But, how the backend API know that user wants to buy that product to an order? We receive the SKU as payload, don't we?
不一定——我们收到 REST API 可以用来计算 SKU 的东西。它可能是别的东西。但是 SKU 很好:从客户的角度来看,主要的一点是消息格式没有改变; 购物者的主要观点是她不必关心有效负载中的内容,因为她有稳定的语义线索可以工作(即:她正在看产品名称,但在封面下提交的表格是 SKU)。
What is the ideal way to map the HTTP verbs, URI, and domain objects?
换句话说:使后端服务看起来像网站的正确方法是什么?
曾经使用网络浏览器配置无线路由器吗?它是如何工作的——路由器的内部结构与网站完全不同。您用来询问堆栈溢出问题的应用程序没有理由用作路由器配置工具。然而它确实如此,因为路由器上的 API 知道如何像网站一样躲避,同时向后端发送正确的指令。
REST 客户端只查看它收到的消息;它对领域对象一无所知;它只知道资源的表示(想想描述事物的文档)。
映射 HTTP 动词等的理想方式,它伪装成一个愚蠢的文档存储。
这是一个迟到的响应,但它可能对正在寻找如何通过 HTTP 实现 CQRS 体系结构模式的人有所帮助。 在我的发现过程中,我决定分享我的发现并最终写了一系列关于如何通过 HTTP 执行 CQRS 的文章。
我特别想指出 RESTful 架构在概念上不同于 CQRS,因此不太适合某个目的。我试图在通过 HTTP 命令一文中对两种架构进行详尽的比较。
除了理论方面,在写作过程中,我设法构建了两个随时可用的独立中间件,旨在帮助您在 ASP NET Core 项目中采用 CQRS。 HTTP Commanding and HTTP Querying.
希望对你有帮助,有什么问题可以给我留言。