今天发生一个离谱的问题
我是个前端开发,有一个列表接口,本来有数据,后面突然列表没了,前端逻辑没动过
我看了看接口,发现接口正常,里面列表数据都在,在控制台打印数据也都正常
最后打印列表字段 rows 发现是 undefined,这才发现列表数据的 key 变成了 data
争论开始了
后端反馈是有两种数据结构,一种是有分页一种是无分页
有分页的接口返回 rows,无分页的接口返回 data
后面甚至提出前端在响应拦截器判断一下,有 rows 的话拿 rows,没有的话拿 data
我觉得很离谱,在我的认知中,我认为后端返回的数据要保持一致性
类似这样
interface ResponseData {
code: number
data: Array | Object // 这里就大概表示一下可以是列表数组可以是对象
total?: number // 需要的话返回
message: string
}

争论半天后端大概意思是:“一般都是这样的,分页和其他查询结果有差异”、“没有必要改 不然看不出来 分页和部分也的区别了”、“你现在没数据了你能第一时间知道是接口改成不分页的了”、“这个框架都几十年了一直都是这样” ...
最后虽然也改成统一的了
但我我对这套说辞是:???
想请教一下大家,你们对接的数据结构也是不统一的吗?哪种方式更好呢?

补充一下

这次可能是后端误操作改了啥,把有分页接口改成了无分页接口,所以 rows 变成了 data

我想说的是,如果数据结构统一了,至少就可以避免这次前端做无用功的排错

不是后端没通知前端,可能是后端失误改了,把有分页改成了无分页,导致 rows 变成了 data

所以我想如果统一接口数据结构,最多可能就是分页失效了,这样前端也能更直观的发现问题

接口一个 key 变了,很难发现。前端一般只看一下接口有数据,就排查别的问题了,这后面的排查全是浪费时间

有分页 GET /users/page 和无分页 GET /users 各一个接口不就行了吗

懒得争论 直接 rows || data

意思是,同一个接口,从有分页改成无分页,并且数据结构变了,还没有通知你,如果是这样,那肯定是后端的问题。

如果是两个列表接口,分别用于有分页和无分页,那这个正常。

我感觉你说的是情况一,后端的锅。

这个没有统一规范,根据具体需求来说。本身这个规范也是由前端后端协商好的,不是由任意一方认为应该怎么就怎样的。所以提前协商好就行。
但是根据描述,这里的问题应该是出现在之前工作,然后现在不工作了?这个按你描述后端也没动?框架几十年了都一样。所以这里应该还是有一方动了??

就算判断一般也不用 key 来判断
要么就分接口
要么就请求的时候通过查询参数是否请求分页
要么就一律统一返回一个格式,limit 设置个特殊标记表示无限比如 -1
不过嘛...最终还是看你们自己的约定来处理

接口不是同一个接口,但返回数据的格式不一样,有的是 rows 有的是 data

这不奇怪吗,万一需要用 data 的时候,rows 也错误的返回不一样的数据了咋办

是的,可能也是误操作改了啥,这个不清楚。但前端排错很麻烦,因为第一时间根本意识不到是 key 变了,看到有数据就检查一下一环了,后面的排错纯粹是浪费时间

确实没有统一的规范,但有些接口是 rows ,有些接口是 data ,甚至要前端做兜底判断,给我的感觉还是比较怪的
不是之前的工作,就是刚才发生的,兼职工作

说框架几十年是说的这个框架都开发出来几十年了,都这么用的,不是公司用了这个框架几十年了

接口是不同的,主要想讨论后端最终返回给前端的数据结构,是不是需要保持一致。不然就会出现这种,后端可能误操作改了啥,前端做无效劳动

无所谓, 心情最重要.

确实

结论:有分页和无分页本质上是不同的接口,所以数据格式不需要保持统一。统不统一都可以。后端给什么用什么。或者按接口文档上写。
感觉 OP 像是新手。其实不用纠结这些细节,能跑就行。项目代码早晚都是屎山。理解屎山,超越屎山。

很离谱,这后端平常靠空指针异常来判断上游是否迭代?

我记得我做的时候无分页和有分页也是两个接口, 我会在文档上写清楚返回的数据结构该是什么样的, 以文档为准

笑死,早晚都是屎山确实不假。我自己的项目我是尽量避免写成屎山,公司项目就没办法了。我之前其实接受了,但今天排这个错排的心累,做了一些无用功。新手也确实是新手,感觉学不完

但你架不住像我这种,后端可能误操作改了啥,然后前端疯狂排错,最后发现 key 变了,排错排了个寂寞的情况

没有文档的前端兼职做起来是这样的, 全靠猜

文档是有的,虽然更新不及时

“有一个列表接口,本来有数据,后面突然列表没了”
这件事重要的不是定义成什么样,而是后端改了东西不告诉前端
你需要强调以后任何修改都必须先协商,至于改成什么样,建议照顾下没水平又脾气大的那方

好像是误操作之类的改了,后端可能也不知道。但我想如果数据格式一致的话,顶多就是分页失效了,还好发现点。我找半天发现是 key 名字换了这不扯淡么

下次多做点沟通试试, 向下兼容一下. 我习惯做了接口改动都和前端说一下, 让前端记得重新看一下文档

好嘞 👍

嗯嗯,明白你说的意思。如果是统一设计的话确实应该尽量保持数据接口的一致性。这种不一致的管理维护都一定的心智和时间成本。

只有我关心今天是周六,应该是休息的吗。。

应该统一结构

分两种结构啊,就像这样:
interface ResponseWrapper {
result: T
message: string
code: number
timestamp: number
}

interface PageWrapper {
data: Array
pageNumber: number
pageSize: number
total: number
totalPages: number
}

如果是一个普通的项就是 ResponseWrapper
如果是个列表就 ResponseWrapper<Array>
如果是分页数据就 ResponseWrapper<PageWrapper>

这跟有没有分页其实没有关系吧,统一字段返回即可。例如下面这种:

{
 "list": [],
 "total": 0
}

后端真没必要在 response 里多加一个 rows 的字段啊...不过如果是老项目的话可能是之前代码里的约定了,他就这么接着写了,那尽量就不要改了;新项目的话找他重新约定下或者让前后端 leader 谈一下吧

考虑到你的表述水平,建议你听你们后端的。

大家都是草台班子,吵得过就听你的,吵不过就乖乖写判断逻辑

之前遇到过差不多的情况,后端如果数据为空返回前段 JsonObject ,如果有数据返回 JsonArray ,很难评哇,本来是分装好的网络请求库的,现在要手动 Json 解析了。

我们是前后端都用 typescript ,用统一的 schema types 管理数据类型,很安逸。。。后端如果 api 接口变了的话,build 的 CI 也会挂,PR 根本 merge 不了

话说像你说的这种后端改动已经属于 breaking change 了,既没有做兼容又没有通知前端更新,属实草台班子

不管数据是什么,一般默认都会要求服务端直接统一格式以及统一字段名处理;
统一字段名,泛型比较方便处理,多个字段命名,那么就得定义多一个字段来处理

你们怎么周六还上班

接口格式一般听后端的,但是文档一定要写清楚。
最好是加上 OpenAPI/tRPC/GraphQL 确保端对端类型安全,能避免很多接口对接的问题。

别骂了别骂了,之前接的兼职 😂

插一句题外话,是不是直接拿 ruoyi 或者其他基于 ruoyi 修改的框架做的系统,因为我对这个操蛋的地方有一点点印象....

后面改了,分分钟改掉了

赞同二楼,写个rows || data兼容就行了,来回 battle 加发帖内耗两三小时就过去了。
大多数系统活不过一两年,人生那么多重要的事,还是多花时间汇报吹 b 向上管理。

是的,所以我感觉很离谱,分不分页还跟返回的数据结构有关联了

难顶

也没,后面拉了个会,后端分分钟改完了

后端是 JAVA ,应该是 Spring Boot

好像是不小心改错了之类的,所以没通知前端,这个倒是可以理解

OP 想的是如果数据结构统一了,至少就可以避免这次前端做无用功的排错。但后端想的是幸好没统一,不然可能很久都发现不了这次误操作。

但我感觉,反而分页失效了能更直观的看出来,比一个 key 变了更能快速发现

问就是 graphql

加个判断的事情,除非有代码洁癖,没有让前端自己去拉数据库增删改查就不错了。

zod.dev 用起来,数据结构不对直接拦住,UI 降级一下把错误展示出来

其实 OP 说的是原先不管是数组还是对象,都放在 data 字段。现在后端改成 data 字段只放对象,数组则放到 rows 字段。这种无厘头行为给 OP 带来了困扰,原先写好的获取数组的接口都要相应修改成取 rows 字段才能正确显示数据。

这不是赛博画蛇添足么? OP 你应该问下后端用 data 返回数组判几年?

是否启用分页我一般给个参数让前段控制,返回结构是一样的

是否分页为什么要换接口,为什么要两种不同的数据方式。后端接口支持传递分页参数(页码、每页数量)不就行了吗?

{
code: 200,
message: '',
data: 列表数据 Array,
meta: { pagination: {当前页码、本业数据条数、是否有下一页、记录总数} }
}

这里一个关键是:事先有没有做出这样的约定?如果有作出约定,那是前端的锅,如果没作出约定那就是后端的锅。至于是不是合理,反而不重要。

升高维度:请他一根烟 或 一瓶可乐,建议改成一致, 不就双方都很愉快嘛

正好前不久遇到过第三方类似的设计
作为后端,我觉得这就是后端设计问题,况且统一的数据结构对后端来说也更简单

看了楼上的评论区,深刻反映出:我国软件水平还非常低,低还普信。

OP 的考虑是对的,对于专业的软工,正确的做法是,只用一套数据结构,在数据结构内部,通过 pageCount 来判断是否有分页。如果无分页,pageCount 为 1 ,表示只有 1 页数据。如果大于 1 页,表示有分页。

楼上那些 2 套接口、甚至 rows || data ,全都是瞎搞。

有没有改,直接看 git commit 不就有了?

我是后端,这个问题从表面上看肯定是后端的锅,同一个接口出来两种不同结构的数据就是不符合规范的。

从根源上说你们整个组都有问题,应该先定规范再开发,而不是中间遇到问题再协商。

即使是遇到问题需要协商,也需要有一个拍板决定的人来决定怎么处理。

往业务链上游走,先从产品经理开始,一渣到底,折磨死后端

我的做法:反正我不该,你爱咋咋地,你找谁都没用

改接口定义已经是违反开闭原则了,还不通知前端,首先后端就是理亏了。数据结构合理性上说,不管是否分页,肯定都是包在 data 里面符合业内普遍做法

之后后端其实分分钟改好了,我就感觉很离谱

无脑 list 。。。。

也不是分页需要换接口,是调用有分页的接口返回的是 rows 。所以这次的情况是后端可能不小心把有分页改成无分页的数据结构,对于前端排查来说看到接口有数据就会过掉,根本注意不到是 rows 还是 data ,后面做的排错都是无用功,这就让我觉得很难受

是这样,之前把有列表的接口改成 rows 我虽然感觉很奇怪但也接受了。这次问题是后端可能不小心改错了,把有分页改成无分页数据结构了,所以 rows 变成 data 了。前端这边排错一般看到接口有数据就排查别的了,根本注意不到 key 是不是变了,后面的排错都是无用功浪费时间。如果都统一了至少不会有这个问题,顶多可能是分页功能失效了,这样前端也能更直观的看出来问题

我这边没后端代码,而且估计是不小心改掉了,前端排错也不会先注意是 key 变了,看到接口有数据就看别的问题了

后端用的 ruoyi 框架,就是这样,主要问题是后端改了没告知前端的问题,定义一个和两个类型没什么区别。

可能误操作改成无分页数据结构了,问题是后端可能也不知道。所以如果数据结构统一,分页改了最多可能影响前端分页功能失效,前端能更直观的发现问题

能一样就一样我觉得没啥问题,谁愿意每个螺丝孔都用不同的螺丝

有的接口在查询参数不同的情况下,返回 pageCount 为 1 就是无分页,有无分页部分接口应该直接在概念上定义好,而不是根据敲一棍子看看出什么 shit 来判断。

理论上来说肯定是一致最好,但是实际开发过程中,看谁强势一点哈哈哈,能叼的过他直接开叼,叼不过默默改前端加个判断,都是草台班子,对于老板来说项目跑起来就行,反正等你离职之后痛苦的是下一位,然后下一位就开始骂祖传代码。

服务端刚毕业吗? 这水平做外包都勉强

其实我意思是,后端说自己没改,直接一起查代码看看。
当然这种做法容易得罪人,但也高效责任明确。不用双方都口嗨。

我又看了一下上下文,很明显我们讨论的完全不是一个东西~
我们讲的是“相同实体的有无分页数据接口”,你讲的是”分页接口的有无分页判断“,很明显,这不是一个东西。

我说头像怎么这么熟悉呢,原来是 B 站的博主啊。加油。

无所谓。争赢了去下家公司还得争

我的意思是,一个接口就够了,根本就不需要为了分不分页去搞 2 个或多个接口。

确实,最后只能还是叼过

没有,后端发现改错了,我感觉失误改错了不是什么很大的问题,我是更在意这个返回结构一致性的问题

好嘞,感谢 👍

那倒也是,但至少我还是想,不管在哪我自己的开发体验都要尽量高一点的

分页和列表肯定都要存在不能为了结构相同而直接简单粗暴统一返回结构。要统一的时候不同数据分页接口的结构和不同数据列表接口的结构。

如果后端是不小心改了原接口的返回结构, 那 100%是后端的锅,哪怕原来的接口不合理是代码逻辑很糟糕也不能随便改。

如果是新接口前端通用请求预期的结构和后端返回的不一致, 那属于前期沟通和前端自测有问题。

另外不建议把分页和列表结构放到一个类型定义中,定义 PageData 和 ListData 即可, 通用接口请求方法根据入参(有无分页参数)很容易区别响应类型。

以前我也觉得后端返回的数据结构应该保持一致,直到后面被安排到其他项目组,里面的后端都是公司呆了 10 多年那种,接口写的十分的丑陋,什么拼音啊,额外字段用什么 xxx1 ,xxxx2 ,xxxx3 前端根本用不上,虽然代码很恶心,但管他的,说不定明年你就跑路了

好像是不小心改错了之类的,所以没通知前端,这个倒是可以理解

听起来似乎完全没有自动化测试的样子,这种真的无语

关于页面需不需要分页这个问题我已经找到真理了,就是统一只提供一个分页接口。想要不分页? pageSize:9999 了解一下,一个接口按你需要随你掉
对接后端接口最怕的就是对象结构会变的,这是对后端最基本的要求,接口对象的结构不能变,而且要统一。别信他瞎几把扯,设计混乱的接口能不能用,能用也能跑,代码和人有一个能跑就行,代码可以是屎山不是我接手就没意见。
不,我也是有意见的,我这个人就是见不得设计的屎的接口。
直接怼后端,别惯着这种菜逼

是个兼职,时间上来说公司这边年底贼忙,已经提了要跑路了

看起来是没有的,虽然前端也没有

盲猜后端用的是 ruoyi