如:请求一本 book 的订单信息
[以前] 1.请求后端 bookinfo 接口,bookinfo 返回 data:{}, 包含了 book 的基本信息,book 的订单信息和订单状态(出售中,下架 等)
2.前端直接渲染数据即可。
[现在] 1.请求后端 bookinfo 接口 返回 book 基本信息 2.根据 bookinfo 接口获取 book 的 id ,再去请求 bookOrderInfo 获取订单信息 3.根据 book id 和 bookOrderInfo 里面订单 id ,再去请求个接口获取订单状态。
导致我初始化页面要发 3 个请求。
想问下 [现在] 这是个什么情况。是后端不愿意给我们包吗?喊他加数据感觉很艰难。很多东西得前端做。如果是这样的话,是不是后面前端可以写 node 来包一层?
1
wangkun025 2022-01-14 11:45:28 +08:00 15
后端的锅。
后端不是菜鸡就是神经病。 |
2
junnplus 2022-01-14 11:46:53 +08:00 1
1 楼说的对
|
3
firhome OP @wangkun025 这个后端好像以前做微服务的。是新来的大佬。现在老后端同学都笑我们是 面向微服务的前端开发
|
4
xmumiffy 2022-01-14 11:48:02 +08:00 via Android
所以才有个东西叫中间层
|
5
zepc007 2022-01-14 11:49:36 +08:00 1
2 楼说的对
|
6
smy14520 2022-01-14 11:49:52 +08:00
数据分开存储的,书籍是一个微服务,订单是另外一个微服务,
|
7
Cowhitewhite 2022-01-14 11:50:00 +08:00 1
什么辣鸡后端,你也应该反驳他
|
8
rbe 2022-01-14 11:50:41 +08:00 5
这种模块拆分非常细致的,很适合用上 GraphQL
|
9
javapythongo 2022-01-14 11:51:00 +08:00 5
你们要一个 bff 中间层作数据聚合
|
10
hecz 2022-01-14 11:51:05 +08:00
拆 12 没问题,第三个看业务场景吧
|
11
ArthurTsang 2022-01-14 11:51:36 +08:00
book 信息和订单信息分 2 接口没问题, 订单信息不含状态有点奇怪
|
12
kylix 2022-01-14 11:52:19 +08:00 1
我做过后端,我也觉得 2 楼说的对。
|
13
jtwor 2022-01-14 11:52:27 +08:00
微服务把业务颗粒化太细了,如果是小项目没必要,让他聚合一下也可以把
|
14
Rwing 2022-01-14 11:53:33 +08:00 1
其实后端这么做也没错,所以一般会有一个 bff 层来处理,而且一般前端人员可以写 bff 层
|
15
swulling 2022-01-14 11:54:15 +08:00
后端可以通过参数来控制
比如 bookinfo 接口默认只返回 book 基本信息,增加 with_order=true 就增加订单信息 |
16
lscexpress 2022-01-14 11:54:51 +08:00 1
其实说白了就是后端懒,多写一个接口整合已有的三个接口信息就完了的事
|
17
AoEiuV020CN 2022-01-14 11:55:57 +08:00 1
这后端就是真的面向数据库编程,只会 curd 了,一个表就一个 curd ,别的让你前端自己搞定,
|
18
hahasong 2022-01-14 11:56:49 +08:00 1
做了微服务拆分,但是应该加一层 api 层专门整合暴露前端接口。你确实成了面向微服务前端
|
19
ragnaroks 2022-01-14 12:03:33 +08:00 2
拆的太细了,你们打一架,谁赢了听谁的
后端赢了你就 request<getBookInfoList,getBookOrderInfo,getBookOrder>().waitAll() 你赢了后端就 return json<getBookInfoList,getBookOrderInfo,getBookOrder>() |
20
einq7 2022-01-14 12:05:20 +08:00
那请问遇到这种情况,该如何有理有据的反驳呢,比如说这种写法有什么弊端呢
|
21
taine221 2022-01-14 12:08:58 +08:00 1
我寻思说这样做没错的
没考虑过前端体验吗 |
22
xuanbg 2022-01-14 12:11:06 +08:00
这个要看具体情况的,一般来说书籍信息不包含订单信息。如果书籍信息只有一个地方使用且需要包含订单列表信息,且订单列表不需要分页的话,这两个接口合并到一起也说得过去。但直接把每个订单的详细信息一次性给你,你有地方显示?不需要点击订单列表里面的订单再跳转订单详情页面?谁会每次都去挨个查看订单详情?你前端就不嫌数据太多接口太慢???
所以,正常情况下,分 3 个接口一点问题都没有。 |
23
totoro52 2022-01-14 12:11:29 +08:00
面向微服务的前端,笑死 , 主要还是看业务场景啊 这样拆也不是不行,就是多了几个请求了,如果要求一起返回的 那最好做成一个,如果是允许部分加载的那就没必要
|
25
xuanbg 2022-01-14 12:18:26 +08:00
第一个接口没什么好说的,第二个接口独立出来的目的是分页加载数据,按书籍为维度的订单,想必上万甚至几十万几百万也不稀奇。你能一次加载???真这样干,怕是要被用户骂死,什么垃圾玩意,打都打不开。第三个接口我就懒得说了,列表都不能一次加载,何况详情。。。。。。列表+详情,怕是 1 本书有几百个订单,系统就要崩溃了。
|
26
fregie 2022-01-14 12:24:47 +08:00 1
接口分的没问题啊,不通接口获取不同维度的数据,你要是有特别的需求要一个接口获取这几类不同的信息,可以加一个接口专门返回聚合过的信息
|
27
3dwelcome 2022-01-14 12:25:43 +08:00
细粒度查询没问题,比如 GraphQL 解决最大的问题,就是能忽略前端一些不需要的属性字段,减少网络流量和等待时间。
但后端这样分段查询的设计,逻辑压力就移到前端的。 我个人做法,是前端做本地缓存优化,每次 AJAX 查询前发给后端,确保一下是否需要取最新数据。 |
28
totoro52 2022-01-14 12:26:05 +08:00
@xuanbg 是的 说到底看业务场景,业务场景允许的 我是能拆多少个就多少个,但有些前端比后端还懒,喜欢在打开页面时就把所有请求打过来,比如很多个 tab 切换时,我是觉得能做懒加载就做懒加载,只有真正需要时才去请求
|
29
mio4kon 2022-01-14 12:26:52 +08:00
缺少胶水层吧
|
30
walpurgis 2022-01-14 12:28:24 +08:00 via iPhone
接口设计要考虑扩展性,没性能问题,原则接口越细越好,方便复用,前端还可以做局部更新
最终性能指标看 sql 执行时间就行,如果一个接口和同时调 3 个接口对数据库是一样的,我会优先分 3 个接口 |
32
xytest 2022-01-14 12:31:02 +08:00
体量不大,就不要把简单的事情复杂化。
|
33
a949690645 2022-01-14 12:32:29 +08:00
我认为很合理
|
34
Macolor21 2022-01-14 12:32:36 +08:00 5
看你们量级多大了,这后端可能是拆分了多个微服务。这种方案也好解决,你们加一个 GraphQL 就可以了,不过相当于你们后端只负责提升接口响应的性能,你们来写组装逻辑。
各有优劣吧,主要看你们业务的量级。无非就是: 1. 需要上微服务吗? 2. 拆分后,胶水层谁来做 无脑否定的人要么蠢,要么只会“啃老”。 |
35
bk201 2022-01-14 12:35:14 +08:00
要么你做一层聚合,要么后端做一层聚合。反正你们之间有个人要做。还有一点就是如果信息量能细化,虽然请求变多,但是能够在一定程度上避免整个应用因为某一个微服务问题不可用。当然,这些可以在聚合层做掉。
|
36
micean 2022-01-14 12:35:55 +08:00
所以用 graphql 搭一层中间层
|
37
ChovyChu 2022-01-14 12:38:34 +08:00
graphql +1
|
38
chairuosen 2022-01-14 12:38:39 +08:00
他拆没问题,拆完要他自己粘起来
|
39
rabbbit 2022-01-14 12:45:42 +08:00
他把数据库也拆了?
|
40
WIN2333 2022-01-14 12:49:12 +08:00
bff+1
|
41
wunonglin 2022-01-14 12:50:18 +08:00
两者都合理,具体还是看业务场景。
但第二种明显更好,毕竟你是获取 bookinfo ,其他东西没必要带给你,你再根据 bookinfo 里面的外键 id 去其他对应的接口查询即可。 这样的话再根据各个客户端的需求,去做就好了。比如页面需要一次性显示,app 不需要,那这样接口拆分的就很合理 再者就是可以“渐进式显示”,打开 bookinfo 页面,先显示 bookinfo ,然后再去请求 order ,这样用户就能先看到页面,不至于要等全部数据出来才显示。 比较复杂的例子:一个 bookinfo 里面,可能有 tags 、orders 、images 、comments ,如果全部给你,数据多的话体验会很差。那我可以先显示 bookinfo ,然后再根据用户点击的 tab ,再去加载对应的数据(懒加载)那体验会好很多,这样系统负载也会小很多,毕竟可能有的用户只是想某几个模块而已 |
42
sunriz 2022-01-14 12:50:25 +08:00 via iPhone 1
一个接口一个资源,这才是 rest api 的理念啊。适用于比较通用的业务场景,扩展能力比较好,接口干净,自描述,比如有些只需要订单,有些只需要基本信息。实际用的话如果只有你一个人用可以做一些妥协,胶水层之类的。但是如果加胶水层只服务你一个场景,放前端也问题不大,因为胶水层解决的也是一类问题,否则也是有些过度优化
|
43
wunonglin 2022-01-14 12:53:44 +08:00
@wunonglin #41
网站人流量多的可以在前端用用中间件做 ttl 缓存,网站人流量少的你也不用考虑多次请求带来的负载。 每个模块都有 curd 了,那就没必要再给你搞一个聚合接口,你说可不可以,当然可以,只是没必要而已。 |
44
wellsc 2022-01-14 12:57:45 +08:00
接口最小化原则也没啥毛病
|
45
rabbbit 2022-01-14 12:59:30 +08:00
想了一下,还是具体问题具体分析吧.
如果是像下面这样, 我觉得 2 是合理的. 1 后台订单管理界面 2 订单按书名筛选 3 从多本书里选一本 -> 展示这本书的所有订单(分页, 且此时不需要显示订单状态) 4 点击订单 -> 显示订单的详细信息 |
46
iugo 2022-01-14 13:00:38 +08:00
如:请求一本 book 的订单信息
前提应该先有 book ID. 1. 根据 book ID 调用 book info. 2. 根据 book ID 调用 bookOrderList 拿到 bookOrderInfo[] book info 和 bookOrderInfo 分开可以理解, 因为是两个业务, 但 bookOrderInfo 和 bookOrderState 分开就不理解了. |
47
2i2Re2PLMaDnghL 2022-01-14 13:16:45 +08:00
https://max.engineer/server-informed-ui
|
49
hhjswf 2022-01-14 13:32:47 +08:00
好奇怪的逻辑,为啥能根据 bookid 获取订单?
|
50
Kilerd 2022-01-14 13:54:01 +08:00
/books
/bboks/{book_id}/orders /bboks/{book_id}/orders/{order_id} 这不是场景的 restful 设计场景吗? |
51
wuxinling 2022-01-14 13:57:33 +08:00
拆分的太细了,没有必要
前年我也这么干过,先拿基本信息,再拿工作状态。 然后前端也是我自己弄(小应用),所有要用基本信息的地方,都要获取工作状态,然后就去改后端拼在一起了。 其实第二种也有好处,我自己也有单独获取工作状态的地方。 和后端说一下拼在一起就行。 |
52
zhangmengyu 2022-01-14 14:00:23 +08:00
拆分微服务没啥问题,但问题是缺少胶水层,前端--A--BCDEF 。你们的问题是缺 A ,前端直接调 BCDEF 了
|
53
nekomiao 2022-01-14 14:14:25 +08:00
单表 curd 谁不会啊,直接用代码生成器几分钟就搞完了,再花几分钟搞搞参数校验,
|
54
nekomiao 2022-01-14 14:15:31 +08:00
哪里的后端工作这么轻松啊,还缺人吗
|
55
lucays 2022-01-14 14:18:11 +08:00
3 个细粒度级别的接口肯定没问题
但是得要他再来一个聚合接口啊 |
56
c1273082756 2022-01-14 14:19:54 +08:00
骂他
|
57
zjuster 2022-01-14 14:21:49 +08:00 1
这就是为了强拆而强拆,完全忘记了后端的本质是为了支持业务(前端)的使用效率。
这该不是是大厂出来的人生搬硬套后端架构吧,非要把简单的事情复杂化。 后端的稳定性和存储架构要漂亮,解藕,易维护没问题,你不能让业务用的时候巨麻烦啊,怎么也要做一些业务视角服务接口吧。 @einq7 屁股板凳问题,要讲大道理都没错,后端理由比较强,因为稳定性扩展性都更强。可以指责后端不了解业务,脱离群众 :) 打一架谁赢了听谁的 |
58
ytmsdy 2022-01-14 14:25:49 +08:00
颗粒度太小了,如果之前做微服务的话,也大概了解了。一般这么小颗粒度的 api ,都会在前面再套一层再给前端用的。
直接给前端用么也可以用,但是就是前端比较费劲了! |
59
C603H6r18Q1mSP9N 2022-01-14 14:37:28 +08:00
5 楼 说的对
|
60
chtcrack 2022-01-14 14:42:52 +08:00 1
按降低服务器负载和提升客户体验来说,这样拆分越细越好,也越灵活.
就是前端比较麻烦些,但是你可以和他沟通,需要一次性拿所有数据下来的时候让他做个聚合..但是你最好别动不动就拿全部数据下来,这样服务器负载加大,客户加载也更耗费流量和资源.. |
61
hun2008hun 2022-01-14 14:49:54 +08:00
没搞懂逻辑,为什么订单是根据 bookid 查;
查询 book 的信息很明显是个基础接口。 |
62
chtcrack 2022-01-14 14:51:57 +08:00 4
前端恐怕不好理解后端为啥要搞这么细化,弄得前端这么麻烦.
按降低服务器负载来说,你一次性拿这本书的所有数据下来,服务器查询数据库假设要 0.1 秒,cpu 占用 0.1%.用户耗费流量 500K. 而细分后,如果客户只是想看看这本书的详情,不看订单,服务器查询数据库只需要查询详情和这点数据,只需要 0.01 秒,cpu 占用 0.01%.用户耗费流量 10K. 意思服务器查询时间和占用 cpu 只是假设值. 一个用户就可以有这么大的区别,如果很多用户一起查询呢? 所以按前端的想法,第一种一次性就拿全部数据的,假设服务器能同时承载 1000 人而不爆炸,那么第二种细分的可能就能承载 3000 人不爆炸,所以你说哪种好? |
63
tabrye 2022-01-14 14:53:13 +08:00
看场景:
1.如果只是 book 单独展示,比如 book 卡片什么的 那当然是以前的方式好 2.如果 book 信息和订单信息要分多个页面分开展示 那还是拆分的好 另外怼后端的时候 建议拉上测试 (..•˘_˘•..) |
64
Hilong 2022-01-14 14:53:19 +08:00
我们后端也是微服务,分了很多个域,但是与前端通信的接口还是有一个聚合域的。这个肯定得后端整合啊。查询数据库肯定比 http 传输快啊
|
65
Jackeriss 2022-01-14 15:03:17 +08:00
少个业务聚合层,一般后端做
|
66
c6h6benzene 2022-01-14 15:07:06 +08:00 via iPhone
我可能会写三个细粒度接口,再写一个聚合的接口吧,然后丢给前端去处理🤣
|
67
sunrain 2022-01-14 15:17:32 +08:00
还好,我遇到过一个更奇葩,会让你请求 bookinfo 参数传 1 ,返回基本信息,在请求传 2 ,返回订单状态,传 3 ,返回.....
|
68
1018ji 2022-01-14 15:26:57 +08:00
BFF
|
69
NCZkevin 2022-01-14 15:37:41 +08:00
当服务规模比较大的时候,这么拆分没问题,但是拆完之后,中间得有个聚合层,聚合层一般也是后端来弄。
|
70
hay313955795 2022-01-14 15:45:59 +08:00
我站后端
|
71
chevalier 2022-01-14 15:51:10 +08:00
让后端学习一下,什么叫 接入层
|
72
lujiaosama 2022-01-14 15:59:54 +08:00
前两个没问题, 拆成三个就有点毛病了.前端加载就刷一堆接口很好玩么,你们前端组长没有意见?胶水聚合层这活如果还要前端写 node, 那还要后端做什么,crud 让前端来写也没差. 不考虑数据获取是否友好的后端嘛玩意.
|
73
manyfish 2022-01-14 16:02:41 +08:00
小项目可以按你说的面向页面开发. 拆细粒度更好维护和扩展, 项目规模变大后,管你什么页面拼接就完事了,剩下的时间来摸鱼:)
|
74
lujiaosama 2022-01-14 16:12:26 +08:00 1
前端后端打架没什么卵用, 真正有效的解决方案是让前端去写后端理解某些场景下拆分接口的必要性, 让后端去写前端感受下接口不做聚合多恶心. 只有前后端一起写的时候才会知道哪里怎么调整才最合适, 而不是前后端各自扯皮.
|
75
weipt 2022-01-14 16:15:53 +08:00 3
回帖的多数时前端吧,一般接口都是按第二种写的,没毛病。
如果按第一个写,那么再有一个 book 库存、book 借出、book 归还等等难道都要写到 data 里吗?可笑。 |
76
hhjswf 2022-01-14 16:27:19 +08:00
@hay313955795 这他妈不是搞笑吗,就为了查一个订单状态单独发一个请求,你司前端不把你头打爆?
|
77
wupher 2022-01-14 16:30:56 +08:00
即使放多表,后端级联或者 join 也是有办法一次取出的。
让你发三个请求纯粹折腾,还把性能消耗到连接握手上。 建议优化吧。 哪怕返回数据包非常大,也不是用这种方法进行优化。 |
78
xiaoyang7545 2022-01-14 16:35:32 +08:00
单纯看, 前两个 还行,毕竟维度不同,第三个纯搞人心态。
|
79
ElmerZhang 2022-01-14 16:53:08 +08:00 1
拆微服务不是这么拆的,应该是后端把原来一个服务拆分成聚合层+几个微服务,而不是只做微服务,让前端去改请求。
你们这个后端大佬八成是个 PPT 党。 |
81
lqu3j 2022-01-14 16:55:16 +08:00
2 是订单摘要信息,3 是订单详情的话我觉得很正常,没毛病,只是一个状态的话就完全没必要了, 至于 1,2 既然是订单,就算体量不大,短时间不需要分页,时间长了,肯定有分页逻辑,我觉得没毛病,总体上来说站后端.
|
82
jessun1990 2022-01-14 17:08:52 +08:00 1
个人想法:
1 、2 拆分开没有问题。2 、3 可以考虑合并。 |
83
preach 2022-01-14 17:23:30 +08:00
GraphQL 的逻辑,大概率是后续用 GraphQL ,应该是挺牛逼的后端,只是没和你说他的想法
|
84
keppelfei 2022-01-14 17:29:35 +08:00
如果是同一个页面,不建议做三次请求,三次 http 握手挺费劲的,如果是微服务可以考虑用中间件来解决状态问题。
对于这种情况可以在弱网情况下展示给后端看看,这样做体验太差了 |
85
pengtdyd 2022-01-14 17:32:18 +08:00
不是挺好的嘛,你看分多清楚
|
86
cr217 2022-01-14 17:34:30 +08:00 1
体现前端价值的时候来了,用 node 写个 bff 中间层。述职时又有东西说了
|
87
labulaka521 2022-01-14 17:34:54 +08:00
最起码数据要一起返回吧,
|
88
linglin0924 2022-01-14 17:36:44 +08:00
我没大看懂楼主的描述 。以前的接口划分:为啥 bookinfo 和 bookOrderInfo 混在一起返回 ?
一个是书籍信息,一个是订单信息,这是两回事吧,不就得拆出来两个接口,为啥要在一个 bookinfo 里返回。 订单状态 也可以单独分出来一个接口。第二种划分业务不是更清晰么?业务接口划分细一点,颗粒小好控制,按需请求。 按照以前的接口 加入商城页面需要获取书籍信息,直接请求 bookinfo 接口,返回的订单信息和订单状态扔掉? |
89
linglin0924 2022-01-14 17:38:15 +08:00
我还没搞不懂,为啥要从 bookinfo 接口返回订单信息和订单状态。
|
90
flighter 2022-01-14 17:42:51 +08:00 1
这个后端要么懒要么菜,只知道数据拆分微服务,却不知道跟随微服务的业务聚合层,这一层是直接和前端对接的
|
91
linglin0924 2022-01-14 17:44:18 +08:00
我还没搞懂,为啥要从 bookinfo 接口返回订单信息和订单状态。
|
92
wunonglin 2022-01-14 17:51:49 +08:00 1
@linglin0924 #89
我认为是因为 lz 习惯了 bookinfo 一股脑带出来可以直接渲染,页面不用太多异步逻辑,加上以前单服务的时候是可以 join 起来也方便,所以直接返回也没什么问题。这是 ok 的,因为那时候大家都这么做的。 但是到现在新微服务架构后,两个服务分开了,分别提供了 curd ,就没必要再加一个聚合的 bookinfo 接口,因为确实没必要。 这个构架不用考虑握手太多的问题。人少对系统没压力,人多接口分细了反而能降低系统负载,前端也可以用中间件做 ttl 缓存。问题很好解决,或者说压根不是问题。 时代变了呀~ |
93
wu00 2022-01-14 17:53:34 +08:00
微服务架构,我们公司现在也这样; 只不过我们对 C 端的接口还是进行了 bff 聚合,B 端(管理后台)的接口也是让前端去请求 N 个接口自己去拼...
后端追求解耦、分治,前端追求减少 http 请求,都有道理,bff 层很多大公司都有专门的“服务于前端的后端”开发人员,遵循服务自治,谁使用谁开发的原则,这东西就应该前端来写。小公司后端来写,毕竟聚合各接口都得走内网,发布部署都不能跟后端分离。 后端同事"笑话"你们成了面向微服务的前端,说明他们是知道这个问题的存在的。 |
95
cnbattle 2022-01-14 18:22:54 +08:00
所以 订单服务里 不用做商品信息 snapshot 吗 ? 有点迷,后端 sb ,拿微服务的噱头偷懒
|
96
gadfly3173 2022-01-14 18:24:01 +08:00
刷新 token 很常见啊,一般是 access+refresh ,act 过期就用 refresh 刷新,拿到一个新的 token 。除非你们 token 刷新之后不变,否则这个设计非常合理。难道每个接口都要预留给你下发新 token 的位置么?
|
97
jeeyong 2022-01-14 18:24:35 +08:00
|
98
learnshare 2022-01-14 18:30:20 +08:00
后端:你看我 微服务、细粒度、业务无关、易于维护、一看就懂
前端:接口要面向业务,不写滚蛋 主要问题是没人把关,各玩各的,互骂傻* 实际上怎么写都行,但一定要达成一致 招人写中间层也行,打死后端也行,折磨前端也可以 从前端 /客户端角度讲,应该尽量避免这种链式请求 几个链式请求的时间和连续几个数据库查询的时间可能相差几百 ms ,甚至几秒 |
99
vance123 2022-01-14 18:33:03 +08:00 2
总要有代码去处理聚合的,不是你写就是他写
|
100
wangkun025 2022-01-14 18:35:06 +08:00
@jeeyong 有道理啊😮
|