REST 业务逻辑和错误处理

REST Business Logic and error handling

我正在尝试制作一个 REST 应用程序,我试图在其中隐藏请求和响应中的业务逻辑。 我有一些我不知道如何处理的例子。

第一个例子:我有一个购物车,产品 x 不能与产品 y 一起订购。然而,客户决定同时订购它们。我如何给出正确的错误消息或指导客户这是不允许的。因为给出一个错误说“xy 不允许在一起”似乎向我暴露了业务逻辑。

由于我们拥有不同的服务,因此结构已经到位。产品可以重复使用,但订单量不同。例如,我们可以在订购布料时为需要不同配置的车辆提供订单接收。在这两种情况下,您都会拥有具有名称和价格的产品,因此可以重复使用。这就是为什么车辆和布料不能也不应该一起订购的原因。为了使这对用户更加友好,将提供一项服务,为特定的订单接收提供可用的选项。但是应该有一个部分可以验证它并给出正确的错误。

第二个例子:客户有一个挂单,挂单完成后无法创建新订单。这 seems/feels 对我来说是有状态的,应该避免。应该如何处理?

UPDATE 因此,解决我的第一个示例的问题可能是创建一个类似于 /products?type=vehicle/products/combinations?类型=车辆。这是为了显示允许的 products/combinations 并有一个端点 /order 将产品放在验证发生的地方。这些端点可以独立存在,但上下文 可能 来自其他地方。我理解正确吗?

我认为您的问题并不完全与 REST 本身相关,但无论如何我都会尽力回答。也许,您可以详细说明是什么让您阅读我的答案感到困扰。

我不是很清楚第一个问题和REST有什么关系,因为我觉得是关于措辞的。我的问题是:为什么不允许同时订购这两种产品?所以,你不能不把它们放在同一个购物篮里吗?这不是真正的用户友好,所以最好的办法是允许它。如果您不能同时更改两者都不允许,那么如果产品 X 已经在购物篮中,我将 "grey out" 所有不允许的项目与产品 X 一起。

然而,这更像是一个用户体验问题。也许,您可以在此处详细说明用户可以同时插入两种产品的确切情况,而这是不允许的。

关于你的第二个问题:在大多数在线商店中,你通常有一个映射到帐户、会话或通过 cookie 的状态。如果您真的想在此处使用 REST 实现无状态 API,您可以使用订单 ID。这些可以传递给每个请求。当然,订单本身是有状态的。但是请求没有。

注意:REST 意义不大。您基本上没有每个请求的状态,并且在 URL 中拥有所有必要的信息。

也许,这已经有点帮助了。

正如另一个答案已经指出的那样,这与 REST 的关系很小,我认为它更多地与 "exposing business logic" 和 "statelessness" 的含义有关。

不想暴露业务逻辑的第一点:只有在某些系统确实需要解释具体错误时才暴露业务逻辑。如果它 "only" 向用户提供本地化消息,则它不会向其间的系统公开任何逻辑。前端系统不需要知道发生了什么,它只需要显示来自后端系统的消息。

在某些情况下,前端系统需要了解,以便能够指导用户。暴露业务逻辑并没有根本上的错误,只要不是隐式暴露,而是显式接口描述的一部分。

关于无状态的第二点:REST定义通信需要是无状态的。这意味着来自客户端的任何任意请求都应该是有意义的 而无需 任何先前消息的上下文(这包括先前的登录、会话等)。每个请求都是独立的。这 并不 意味着特定资源无法保持自己的状态。后端的购物车确实有一个状态,这没关系。

或者换句话说:下一个请求是否可以命中不同的服务器并仍然成功?我的意思是没有会话复制、分布式缓存或其他魔法。如果是,则通信是无状态的。如果你需要 "sticky" 会话或类似的东西,那么不,你不是无状态的。