![]() |
1
bigfei 131 天前 ![]() 自己建立个 BFF 层,扩大代码的 ownership ,防御性编程。
|
2
Gil86002618 131 天前 ![]() 写个 BFF 层处理吧,其实服务端说的也没错,有些服务就是基础服务,跟具体的业务无关,需要考虑接口的通用性。
|
3
hging 131 天前
你想想如果明天产品跟你说 要再加一个数据 那你是让后端给你加接口方便还是用通用的自己接方便。
|
![]() |
4
lambdaq 131 天前 ![]() 接口原子性最后的进化就是客户端直连 sql 。
|
![]() |
5
woodfizky 131 天前 ![]() 设计上应该保持各个方法/接口的原子性,但是给到前端的接口可以根据业务具体情况让后端自己整合一下。
当然也可以不整合。 但是图片分两张表/两个接口有点奇怪,两张表不是可以联表查出来一起给到前端嘛,反正都是 url ,又不会有多大。 我只能说你举的例子不够明确具体,最好给个例子。 |
![]() |
6
unco020511 131 天前
可以自己加个中间层处理下,对于你的业务还是调一个接口
|
7
vacuitym 131 天前 ![]() 其实分开比较好,你想一下四个模块有一个出问题了,你希望是只有三个模块数据正常展示还是说四个数据全部无法展示
|
8
FEontheway 131 天前
让后端再另外提供一个聚合接口调这个通用服务不就行了。而且多个接口同时调用,各个模块展示顺序也不好控制,不会影响用户体验吗
|
![]() |
9
lzgshsj 131 天前 ![]() 为什么要反驳?用着不爽就自己弄 BFF 。另外这种事情不应该让你们的 leader 定调吗
|
10
JoeDH 131 天前
|
11
NessajCN 131 天前 via Android
没太懂,你是希望后端专门为你写个接口,把其他接口已经提供的功能和数据整合到这个接口给你,方便你只用请求一次就能获取全部数据?
|
![]() |
12
lithiumii 131 天前 via Android
@eastjoehan 我遇到过要求能直接写 SQL 查的,这不是完美符合
|
![]() |
13
helone 131 天前 ![]() 你可能刚从业没几年吧,之前我对接的移动端反而觉得后端一个大而全的接口不好,一旦业务或者页面变更,整个接口都要做大变更和重做一个页面没区别,如果分拆开来反而能复用部分之前的代码包括容错的逻辑
|
![]() |
15
fnd 131 天前 ![]() 你们的后端太懒了。就你说的这些情况,需要有一个专门的业务后台来做这些接口的整合,而不是客户端做这些事情。
|
![]() |
16
vincent7245 131 天前 ![]() 这是最基础的架构啊,基础服务 -> 业务代理层 -> 客户端/前端,按照你的描述,是不是你们后端没有做代理层,你直接访问的基础服务的接口?那就自己在客户端做个代理层呗
|
17
brader 131 天前
>大部分页面通常都要 2-5 个接口。 首先这个现象是正常的,你随便去看哪家大厂的产品,只会调用的更多。
然后从你描述的情况,总结为后端出接口可以有两种方式:1 、按页面来出接口。2 、按功能模块来出接口。 这两种其实都行,都可以实现需求。我个人觉得后端怎么出你怎么用(不合理的接口除外),没有必要非站你角度去强迫对方按哪种方式出接口,只会增加无畏的争吵 |
![]() |
18
zephyru 131 天前 ![]() 这种情况感觉就是,SaaS 中台或者叫业务层与底层服务的区分,后端不想有 UI 的业务代码入侵后端,从设计上考虑其实无可厚非,无非就是 UI 的业务逻辑在哪一层聚合的问题,BFF 层可以后端维护,也可以前端维护,可以写在服务端也可以写在客户端,无关对错只是一个策略问题,你要是有能力可以推进后端针对业务抽象一层出来也不是不行,不好推就自己抽象吧
|
19
ilovegaojianfore 131 天前 via iPhone
我作为十年老 iOS ,也觉得分开给比较好,我不喜欢一个接口包罗万象。
|
20
liumao 131 天前
这图片表为啥要分开存,啥呆逼设计
|
![]() |
21
xFrye 131 天前
我反过来了,非常不喜欢一个接口给我返回所有的数据
|
![]() |
22
MoYi123 131 天前
专门为你的页面写个接口是没道理的.
可以让后端提供一个能一次性查询多个接口的方法. 大概下面那样. req {"data": [{"uri": "get_user", "body": {}}, {"uri": "get_time", "body"}]} resp {"data": [{"uri": "get_user", "resp": {"id": "12313"}}, {"uri": "get_time", "resp": "2024-4-29"}]} |
![]() |
23
MillaMaxwell 131 天前
后端,这种并不是 pua,全部丢一个接口里只会增加维护的麻烦程度
|
![]() |
24
lsk569937453 131 天前
去哪儿的 app 首页有二十多个接口。
|
![]() |
25
aino 131 天前 ![]() 后端给你什么就接着就对了
|
![]() |
26
angenin 131 天前
@liumao 我觉得应该是,有一张专门的图片表,而其他表的图片字段(例如用户表头像)只存图片 id ,前端需要通过图片 id ,调一个图片接口获取图片的实际路径,再获取到图片。(我们之前的项目,领导就是这么设计的)
另外,关于接口方面,可以两种都兼容,基础服务的接口也提供,如果某个页面需要调用的接口太多了(比如十几个?),可以要求后端再单独提供个大接口,前端第一次调用调大接口,局部刷新也能用基础服务接口。 当然可以跟 leader 反馈下,看领导安排。 |
27
Philippa 131 天前 ![]() 你说的实际例子,要先获取 id 和然后跟据 id 取请求接口这个做法非常普遍。
后端不需要关心展示逻辑,而是关心数据逻辑。高度集成的接口其实把展示逻辑也丢给了后端,进行变动时需要前后端同时处理,所以前后端的确需要分离数据逻辑和展示逻辑。 很多前端都想一个 API 获取所有数据,巴不得镶嵌结构也刚好是页面的结构,但那样就耦合了业务逻辑和数据逻辑了。但这个是不可能的,你看看 GraphQL 一个 API 的结果就是前端还要熟悉表结构…… |
![]() |
28
uiosun 131 天前 ![]() 保持原子性不是提供 SQL 让前端自己查——接口层面的原子性是后端不写重复的 [业务接口] 。
你们后端直接一步干到“后端不写业务接口”了,那还要后端干嘛,直接 GraphQL API 给前端,后端转岗前端完事了。 |
![]() |
29
8355 131 天前
可能确实是你认知问题。。
app 本身是需要兼容老版本的,你一个接口返回太多东西以后怎么兼容,后端做版本判断? |
![]() |
30
cedoo22 131 天前
一个耗时 200ms 的接口 包含所有,
4 个每次耗时 20ms 的接口 , 你怎么选?? 除了前端外, 后端、leader 基本都会选后者 |
33
htxy1985 131 天前
图片分成两个表是为什么? id 和 url 的关系还留着扩展成一对多,多对多的可能?
|
![]() |
34
BiChengfei 131 天前 ![]() 你是客户端,他是服务端,大致属于 B/S 模式,服务端皆苦应该符合外观模式,对客户端隐藏系统的复杂度。应该针对不同的客户端封装不同的接口
|
35
lazyfighter 131 天前
需要一个聚合层, 面向 C 端的一般都不是原子性的接口, 聚合服务支持业务逻辑面向不同端的定制, 此时你只需要反驳一句,如果 web 跟小程序逻辑不一样,那你后端接口是否还是原子性的, 原子性没有问题但是更多的是面向自己的服务领域做到高内聚低耦合,当真正的面向 C 端业务场景的时候,我们应该做的是聚合多个原子能力,对外输出业务场景能力。
|
![]() |
36
angenin 131 天前
@htxy1985 对,有可能是一对多,如果金融行业,用户的实名认证信息,过期了要补充新的,但不能删除以往的图片,在图片表里记录用户 id 和图片类型,必要时可以查出所有以往的材料,也不叫图片表应该叫文件表。
|
37
dongtingyue 131 天前
图片那个例子不合理吧,原子性不是这样定义的。
一个请求变两个请求,前端并发量也成备。 |
![]() |
39
wangritian 131 天前
后端这样设计是合理的,上面有提到 BFF 层,还可以在前端封装一个并发请求,合并拿返回数据的通用方法
这要求后端需要支持 h2 协议,必须支持 |
![]() |
42
james2013 131 天前 via Android
这是后端问题多点
我讨厌后端只提供增删改查,而不是根据界面开发接口 |
![]() |
43
qeqv 131 天前
减少精神内耗,把情况和领导/老板反应,权利是自己争取的。如果争取失败了也可以心安理得地接受
|
![]() |
44
Rehtt 131 天前
一个 200ms 包含所有数据的请求和 4 个 50ms 的请求,如果配有负载均衡这 4 个请求可以被均衡掉减小对服务器的压力
|
![]() |
45
lasuar 131 天前
既然你没有太大话语权,那就听后端的吧。职场中没有绝对的技术权力。
|
46
iOCZS 131 天前
promise.all[]解君愁
|
![]() |
47
shengchao 131 天前
让后端同一个服务支持类 jsonrpc 那种查询就可以了
由单一 obj 的 json 扩展成数组,例子如下 req: {"method": "getrawtransaction", params: ["aaa", "bbb", "ccc"]} => [ {"method": "getrawtransaction", params: ["aaa", "bbb", "ccc"]}, {"method": "sendMessage", params: ["aaa", "bbb", "ccc"]}, ] |
![]() |
48
chengxy 131 天前
一个数据列表返回了 10 条数据,每条数据上都有 5 个图片 id ,前端先调取数据接口,渲染的时候再分别调取 5 次图片接口,除非图片接口可以直接返回图片,否则我是接受不了。
|
49
wumou 131 天前 ![]() 我觉得两个人都没错。
问题是层级少了,缺少一个负责聚合数据的中间层。 |
![]() |
50
aduangduang 131 天前
加一层 graphql
|
51
blessingcr 131 天前
不懂前端,但是后端这样做合理的
不过可以让后端多提供一个聚合数据的接口 |
52
wangmn 131 天前
能跑就行
|
53
12471220 131 天前
就是后端懒,所有东西不想动全交给前端处理,还美名其曰原子性
|
![]() |
54
lwjlol 131 天前
人家没毛病,接口设计尽量简洁,不要大而全,至于你想一下子把数据请求全了,可以自己二次加工,在自己的 repo 层合并
|
55
jjx 131 天前
后端是对的
后端服务应该可以被组合使用, 这样前端可以获得最大的灵活性和扩展性 否则后端服务就是死的 前端如果认为四个调用在一组,写个函数处理一下不就得了 |
56
sampeng 131 天前
说服不了就加入
|
57
Huelse 131 天前
那你就不优化了,按他们的要求写,只要有一个接口慢了出现卡顿就怪他们头上去
|
![]() |
58
levintrueno 131 天前
@helone A 站肥肥?
|
![]() |
59
rxswift 131 天前
一个页面 5 个接口很正常
|
![]() |
60
NilXuan 131 天前 ![]() 我是写后端的;
「服务端考虑到后面可能其他的服务也会调用,所以希望能尽可能通用」这句话看起来也没有问题,保证接口的单一职责的确很重要,但归根到底,这是接口开发者的职责,不是接口使用者的义务; 如果「单个接口返回需要的多个数据」需求是成立,那么接口怎么实现以及将来怎么复用是后端需要考虑的问题,后端只要提供这个接口就好,不能教对接方做事吧; 但是「单个接口返回需要的多个数据」是否真的成立,比如不在一个接口返回,非常难渲染界面; 如果仅仅是因为「数据是同一个服务提供的」就希望「一次将这个这四个模块的数据整体返回」在我看来这是不够具有说服性的——这相当于将前端组合接口的工作转移到了后端(属于“损人利己”),所以后端需要拒绝,然后就找了一些通用啊、复用啊这类的“说辞”(虽然也有道理) 至于 pua ,九字真言呗; 吐槽归吐槽,还是要解决问题:给后端一个不能拒绝的理由很重要;如果只是针对某一个人,为了维护自己的利益,那么引入第三方——各自的 leader 或者资深程序猿,也是一个方法; |
![]() |
61
daysv 131 天前
后端思路是对的,对前端一个潜在好处是不用等全部数据查完再渲染, 可以分接口分块渲染。
|
![]() |
63
Sfilata 131 天前
我觉得这就是两码事,后端接口原子性是一码事,数据聚合又是另一码事。其实本质问题就是看新加的业务数据聚合层到底是谁做,如果后端负责就让他去做,如果要放到前端,那就你去做呗。写个 Promise.all 的事
|
64
kamilic 131 天前
「比如之前获取图片,因为他们的图片是两张表,一张是图片 id ,一张是 id 对应的图片地址。我只能先获取 id ,再用 id 去请求接口」
这种完全就是 sql 的逻辑,客户端为什么要关心对接方的内部设计,把接口细节暴露出来增加对接方理解成本真的很好? 你对接的后端做着业务后端的工作,但用着基础服务的心态提供接口。同意前面大佬所说的,提供一层聚合层/业务后端层来解决这个问题。 我觉得客户端使用的接口就要提供视图所要求的数据,试想一下如果产品以 api 接口提供对外服务,提供这样的 api 能力,感觉客户得把你骂死。 自己人折磨自己人也是很正常,这些 dirtyworks 谁都不想做,但总是要做,就看公司内部话语权了。 |
![]() |
65
dododada 131 天前
@eastjoehan 你这个我见过,整个业务就一个接口,数据用协议来定义,统一加密处理,就是有的时候 body 有点大
|
66
darklost 131 天前
上 graphql 然后把自己玩死;)
|
![]() |
67
Hilong 131 天前 ![]() 也就是你们前端没有话语权,楼上还有让前端自己写 bff 层的,在我们这里直接怼后端,你怎么原子化跟我没关系,整合好了吐给我。后端也可以搞个 bff 层的啊
|
![]() |
69
orzwalker111 131 天前
@liumao “业务存路径”,哪天如果要统一清洗文件路径,这个工作量?附件系统也是一个单独的底层服务,对外只提供 id 是合理的。联表查询——附件一般是个大表,这块会不会有性能问题。另外业务中可能要获取这个图片的“大图、中等图、缩略图”,具体的文件和附件表甚至在两个不同服务中,比如“图服务”、“附件服务”,这块用两个接口去取附件数据也是很正常的设计,没有很呆逼。
|
70
Richared 131 天前
如果后端只是提供能力,那么就前端做,我们在中间会有其他后端同事负责接口聚合给前端使用。看流程,如果就两个人,商量着来呗,谁活少谁做。
|
![]() |
71
wolfie 131 天前
聚合查询跟原子性没关系。看你们关系好不好、性格硬不硬。
图片地址那个 100% 后端问题。 |
![]() |
72
Nich0la5 131 天前
图片和图片 id 分开是大量图片的情况下可以自行进行动态加载吧,设计上没问题,不过听你说的样子好像你们这个项目其实没这个需求
|
![]() |
73
darkengine 131 天前
@cedoo22 200ms ,20ms ?你们用户跟服务器在一个内网吗?
|
74
ZGame 131 天前
graphql 就是用来做这的
|
76
ZGame 131 天前
我觉得要转换思维 不要和后端去对立 ,打个比方后端如果不做聚合的话,那么很多数据拼接的工作就需要在前端做 ,那你就可以多报工时,而且更好的是自己用 next.js 去做一层 bff 层, 反正让加工时就好了
|
![]() |
77
wu67 131 天前
单个后端应付多客户端的时候, 每个客户端要他写一套, 要写趴后端.
但是如果给通用接口, 某个特定客户端需要不同数据时再单独给你写, 他压力会减轻很多. 当然他自己聚合一下也行, 只是大部分情况开发时间都不允许他再继续加码罢了... q: 大部分页面要 2~5 个接口? a: 一个界面 10 个接口我都玩过... 还是我接手之后把接口往上层组件提取出来了的结果, 不然每开一个对话框又要请求几次重复的接口... 当然就事论事, 请求图片这个我也觉得有点离谱, 不知道怎么吐槽. 反正我现在写前端都是自己组数据, 管他后端怎么写, 反正有足够的数据给我就行, 扯皮太累了. |
![]() |
79
GotKiCry 131 天前
上面发癫,你下面只管在代码拉屎就完事了
|
![]() |
80
qweruiop 131 天前
加一层 graphql 直接解决问题。
|
![]() |
81
darkengine 131 天前
@ZGame 对于加工时他们还有一个说法,“不就加个按钮”,“不就显示个列表”
|
![]() |
82
shizhibuyu2023 131 天前 ![]() 说破天也是后端偷懒,要是我就直接在业务群 @后端 leader 开喷了,什么鸟玩意。对方还是不妥协就加 bff 层,然后每次需求都提一嘴「因为后端偷懒,我们前端会延长排期」。然后摸鱼时间++,哈哈。
干他妈的就完事了 |
![]() |
83
Hyakutake 131 天前 ![]() 你如果只是想说服他,可以从原子性的缺点出发。
如果你想你自己爽一点,是不是可以从设计模式出发,例如用外观模式封装一层,就好像和楼上说的一样,别人不愿意改,你可以改。 刚好最近在梳理设计模式,外观模式如下: https://hi.hyakutake.site/posts/design/Facade |
84
loveumozart 131 天前 via iPhone
其实如果我是后端,会乐意做这种事情,扩大领域一可以多一些排期,二可以有理由招人加影响力
|
85
han3sui 131 天前
图片那个不合理,详情类的应该把图片信息带过来。
|
![]() |
86
Helsing 131 天前 via iPhone
我觉得后端没问题,从最少知道原则来说,我这个页面明明没用到的数据,后端就不应该返回
如果你的 app 是设计成处理这种大而全的借口的,我怀疑你的 app 架构设计都有问题 |
![]() |
87
laobobo 131 天前
之前项目也有类似的场景,一个页面好几个接口取获取数据,后来来了一个大佬,给整合了一下,一次把所有数据都返回了
|
88
zealotpuppy 131 天前 ![]() 除非你写的东西一辈子都不会改,否则学会模块化。不管是后端业务还是前端渲染或者两者交互的接口。
使用一个大接口,以后改一次就欲仙欲死。页面出问题,排查过程也太过复杂。 以一个典型的商品展示页举例,展示图、库存、价格、详情、退货条款,你确定要把这些东西全部放一个接口? 怎么有些前端的还想争话语权?我知道这里前端多,可是前端又不需要承担业务责任和架构设计,你们怎么争话语权?能不能做,怎么做是后端说了算。 |
![]() |
90
NerbraskaGuy 131 天前
还是得看具体情况分析,有些情况是绝对不能接受的,比如用户信息明明可以一个接口全给,非得做成用 ID 遍历去查,这种完全就是后端偷懒了,包括你这个图片的请求方式
|
![]() |
91
mcluyu 131 天前 ![]() 真是一堆大佬,前端需要管你后端什么原子性,什么架构设计吗,那是前端需要关心的事情吗?业务接口就是业务接口,你见过谁家提供的服务会让你加载张图片还要请求几次才能拿到图片 url 的,居然还有让前端来写 bff 的。。。。 还有啥一个接口 50ms ,四个一起查就要 200ms ???我直接?????
也就这些年终端的网速带宽都明显快了, 不然一个请求来回几百 ms , 加载一个东西你要请求好几个接口那不得慢死了 |
92
ma836323493 131 天前
@qwertyzzz #40 #40 后端更方便, 但是有的数据量大,有的数据量小,分开接口查询是正确的, 否则数据量大的接口卡死了,小的 一个接口跟着遭殃
|
![]() |
93
huajia2005 131 天前
我觉得模块化是没问题的,大而全的接口应该尽量避免,这样不管排查问题,还是后期改动都会方便很多
|
94
yule111222 131 天前
这后端不行,只要在接口层在包装一个 Facade 接口不就好了,细粒度的接口依然可以保留
|
95
lscho 131 天前 via iPhone
说破天也是前端该去整合数据。。。。
上面还有说让后端整好数据吐给你,后端怎么知道你要什么数据?后端还得去看设计图不成?前端就当个切图仔? 业务代码是业务代码,数据整合是数据整合。总有懒前端试图想混为一谈想让后端全搞了。 |
96
AceDogs 131 天前
你的方案和后端的方案都可以实现需求,看场景和情况选择。我自己的经验来说,我支持后端的方案,后续的升级更方便,前端在不同业务上也许可以复用更多的接口。
对前后端都好,调用接口数量多不一定性能差,还是要看运行环境和场景,有时候可维护性也挺重要的,调用一个接口表面上是一个,实际上响应时常不一定更快,场景不同的情况下效果也不同。 |
![]() |
97
mcluyu 131 天前 ![]() @vacuitym 你觉得请求四个接口遇到网络波动的概率大还是一个接口遇到波动概率大啊,简单查询接口的请求时间绝大部分不是消耗在网络延迟上的吗,服务器查询一个和查询四个的时间哪怕你一个个查那可能也就是 5ms 和 20ms 的差距, 一个网络请求和四个的时间差那就完全取决于网络了。
网络波动请求一个成功概率如果是 70%, 我只需要成功一次就能显示完全, 请求四个那我全部请求成功的概率直接降到只有 3 成不到了 |
![]() |
98
JingXiao 131 天前
爱改不改,不改的话大不了多写两行代码循环请求一下,又不是不能用,日报还能多写点工时「联调了 xxx 接口」。反正扯皮的功夫都写完了
|
![]() |
99
iyaozhen 131 天前
就你举的例子来看,我站后端
现在是 4 个模块,加一个、减一个怎么办呢 我只能先获取 id ,再用 id 去请求接口。这种也很常见,先返回摘要列表,再按需查详情。 但我了解你的意思,有时候设计的很好,但就几个用户,几个开发,过度设计了。说不定几个月后产品都下线了。但怎么说呢,看公司规模和氛围吧。就相同功能来说,大厂和小厂开发时间能差几倍,是大厂效率低嘛,可能是吧,但个人感觉是精细活多了短平快不太会了 |
100
lxy141 131 天前 ![]() 首先最细颗粒度的接口肯定是要存在的,不管是否暴露给前端用。这是后端不能避免的工作量
然后业务数据的组合,就看是谁来做了。从技术上前后端都可以做。就看开发资源的比重了,如果后端看法资源比较多,那就后端做,不然就前端做,因为整体的开发量会相对更低。 但有一种例外,就是业务数据本身有原子性(不是单表的原子性),譬如多张表的数据变动是联动的,且受到其他请求的影响,那就应该后端来出一个包含所有请求的业务原子性接口。 就 op 给的那个图片的例子,其实这个例子举的很抽象。因为不可能有人把图片 id 存一个表,再建一个存 id 和链接映射的表,如果是这样的设计,第一个表完全不需要存在。所以第一个表更大可能本身放的是其他数据,例如用户数据,有个字段是关联用户头像的,存了一个头像图片的 id ,然后单独把头像图片存了一个表 。这种设计是有可能的,这种就属于前端和后端谁做都可以。 一般这种事,整个公司应该有技术方案的设计规范来确实,大部分的业务数据组合是谁做,有什么特例情况等等。不是两个研发自己争辩一下就可以确定的,确定了这一次,后面还有无数次,还是要指定规范。 |