RESTful 风格下,一个 Action 需要对多个资源操作要如何理解?

2018-08-07 11:25:40 +08:00
 ifane
比如前端有一个按钮,这个按钮表示「去结算」,这个「去结算」代表了后端需要执行一系列的操作:更新订单资源,创建该订单对应的物流资源,更新用户余额。

这个系列的操作如果交由前端来逐个调用:先调用 A 接口表示更新订单,A 成功返回 200 再调用 B,B 成功返回 200 再调用 C.
感觉这样实现不太合适。
10524 次点击
所在节点    Python
53 条回复
passerbytiny
2018-08-07 13:46:21 +08:00
该按钮怎么处理,完全是 UI 自己管的事,Restfu 接口设计时完全不用考虑该按钮要干啥。它需要考虑的是:购物车资源,应该暴漏一个结算行为供远程调用,所以 Restful 接口提供的资源是“购物车 /{id}/结算”。(“资源 /动词”表示资源的某个行为,是合法的 restful 风格)(相应的,UI 那里也只需要调用一下这个接口就可以,它完全不用考虑后续的业务是怎么处理的)

至于 restful 接口之后的过程,就要涉及到领域模型相关的知识了,这个一时半会说不清楚。大致提一下过程( restful 接口只需要调用购物车的结算方法,不用关心后续过程):
购物车:结算
——》结算事件:被发布
——》新建订单监听:处理结算事件
——》订单:被创建
——》订单创建事件:被发布
——》
[并行] 用户相关监听:处理新订单事件——》用户 /用户余额:减余额
[并行] 物流相关监听:处理新订单事件——》物流:新增
[并行] 更多相关监听

有一个非常重要的点是:要使用 restful 接口,必须要一起使用领域模型设计,而且是启用了领域事件、异步、最终一致性的 DDD。如果还是传统的纯事件驱动模型设计(界面点个按钮,后面巴拉巴拉怎么处理),就不要用 restful 接口,强行使用(比如说动词名词化),很 S B。
lygmqkl
2018-08-07 13:52:28 +08:00
POST /orders //如果是从 shop cart 直接到订单系统
PUT /orders/o_id //如果是存在订单做后续更新

然后放到 Model 层 来处理,可以用 Transaction

具体还是要看架构设计了
mooo
2018-08-07 14:21:48 +08:00
为什么要定义 3 个接口,REST 是抽象的资源又不是具体的表。接口定义一个 PUT 订单就可以了
zhzer
2018-08-07 14:29:28 +08:00
这种情况要用 restful 除了前端调用起来麻烦,权限管理也是个问题
最好的方法就是不用 restful
thinker3
2018-08-07 17:16:04 +08:00
@transaction.atomic
@action(methods=['post'], detail=False)
def settle(self, request, *args, **kwargs):
zvving
2018-08-07 17:25:08 +08:00
资源 != 表
资源 == 业务场景实体

业务场景实体的转换( A->B )和修改( A.a = 2 )都可能导致表修改以及大量业务逻辑。

问题 1: 去结算
根据购物车的数据 POST Order 就好,"更新订单资源,创建该订单对应的物流资源,更新用户余额" 这些都是后端逻辑,前端不要管,管了也不安全

问题 2: 有些场景会有接口 1 调完调接口 2,一般都是接口设计不合理,比如问题 1.

RESTful 不是银弹,但能满足国内 80% 中小企业的绝大多数场景。而且绝对比开发随意定义的结果好得多。先学会,再去喷……
zvving
2018-08-07 17:29:59 +08:00
@est “发明 RESTful 的人就是个做外包忽悠人的。”

真是什么话都敢说。不知道你跟 roy 比,谁是做外包的!

“ Roy Fielding 的毕业论文。这哥们参与设计 HTTP 协议” 出处: https://www.zhihu.com/question/28557115
unforgiven
2018-08-07 17:34:10 +08:00
@est 人家好歹也是发过 paper 的,再说了 restful 又不是只对应数据库的一张表,看你怎么抽象
est
2018-08-07 17:52:26 +08:00
@zvving

http 也并不是什么好协议。或者说 http 并不是什么场景都适用的。Roy Fielding 也不是什么好人,或者说他的一些观点在当时可能有用。RESTful 发明的时代是 http 1.0 时代。那个时代的东西被淘汰的太多了。他发明的 SOAP 你们今天还有人用嘛?

Roy Fielding 后来去了 Adobe,按照他老人家的思路去搞了 CodeFusion。这玩意你们有做过嘛?简直各种别扭。


为毛 RESTful 就那么多人捧臭脚?搞不懂。RESTful 在过去唯一拿的出手的就是 WebDAV。其本身就是各种安全和性能问题一坨浆糊集大成者。其本身就是个 leaky abstraction


@unforgiven

RESTful 在上古时期(UUCP 还是个事儿的时期)可能有用,但是现代复杂业务场景下就是胡闹。
unforgiven
2018-08-07 17:54:56 +08:00
@est 那这就属于理念不同了,反正对我这样讨厌起名字的人来说觉得 restful 还不错
est
2018-08-07 17:58:53 +08:00
@unforgiven 其实就算 db 里一张表,我觉得现代的用处也远远超过了增删改查。

比如 upsert。 比如 on duplicate key update。比如 update a = a +1

这些都是 fetch-then-update 的操作。有些还得做线程安全。这些我觉得都不能简单的概括。RESTful 根本不能覆盖这些情况。

就拿最简单的 GET URI 操作来说,页面访问量计数器算不算状态的改变?多次刷新 GET 能否保证幂等?这些问题都是各个人都有一套自己的答案。

RESTful 是属于蛮荒时期一个方向性的指引,是个不错的大框架。但是现在应用场景那么复杂精细还用这个框架去套就不对了。应该具体业务用不同的方案。
newtype0092
2018-08-07 18:08:58 +08:00
@est 感觉你说的前后矛盾啊
#7 “世界上对资源操作的行为这么丰富”
#16 “我觉得 GET 读 POST 改就够了”
所以到底应该怎么样抽象操作啊?
unforgiven
2018-08-07 18:09:24 +08:00
@est 说个实在话,我觉得你非要揪住 restful 不能覆盖的情况来看就没啥意思了,就拿后端的管理系统来说一般就是 crud,是不是很适合,没有完美的解决方案,看你自己的选择了
zvving
2018-08-07 18:14:19 +08:00
@est 你说的问题存在,所以说 RESTful 不是银弹。

RESTful 实体的思考方式有利于梳理大部分的业务,特定场景用别的方案,用呗。怕的是 API 设计一味造轮子,纯把业务搞乱。

看看主流 Web 框架对它的支持,我也乐于捧 RESTful 的臭脚。
est
2018-08-07 18:25:20 +08:00
@newtype0092 不矛盾。对资源的操作太丰富,所以规定 2 个大类就够了。4 个 verb 明显不够。比如 OPTION 在实际中就少不了。。。DELETE 也是有 2 意的。其实很多删除并不是删除。而是设置一个已删除的 flag。
@zvving 其实我比较支持对 资源 的梳理,我主要反对 REST 里把 verb 定义成 4 种 这种做法。太死板了。
sfree2005
2018-08-07 18:39:10 +08:00
可以上 GraphQL, 它出现的目的就是为了不用前端 /移动端进行多次请求。 台式机笔记本还好,但如果是移动端,多次请求费电费时间,体验不好,万一中间有网络不稳定的情况,事情就变得很复杂。
tomxin7
2018-08-07 18:46:01 +08:00
让后端提供下单接口,你只需要提供需要结算的商品信息就好了,到支付这一步又是其他页面其他接口了。
lscho
2018-08-07 19:19:20 +08:00
这个问题搞不明白的感觉都是前后端混写的吧。。。restful 资源是抽像资源啊,又不是具体到数据库。

比如 put /order,表示创建一个订单,与创建订单相关的数据需要更新,后端想咋写咋写。只要暴露出来的接口是这个规则就行。

再另外,restful 也只是一种设计风格,并不一定要完全死搬硬套。
duan602728596
2018-08-07 23:52:53 +08:00
没错,就是不合适,这么干用户不找你麻烦算我输。我之前的公司,后端就是这么个水货,复杂的、涉及到多表的功能就要发送 5、6 次请求,有一步失败了,数据库里就一堆垃圾数据。美其名曰风格,实际上就是给自己的懒惰找个借口罢了
newtype0092
2018-08-08 00:05:53 +08:00
@est 我现在只是简单的把只读幂等的一律 GET,有写入的一律 POST,感觉很难把 RESTful 和实际的业务结合起来。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/477542

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX