后端传过来的某些属性不固定,有时候有,有时候没有,这样合理吗?

2021-01-26 14:49:31 +08:00
 darknoll

比如和后端商定好了,返回的接口格式是: { "A": "", "B": [{}, {}] } 这时候后端说了,B 的数据有时候没有,如果没有的话就直接返回{A:""} 我让他返回{"A":"***", "B":[]}

哪种方案好?

15648 次点击
所在节点    程序员
187 条回复
guyeu
2021-01-27 10:24:06 +08:00
这种难道不是前后端商议通信协议,共同定义协议( protobuf 、json scheme 、dsl ),分别生成基于前后端技术栈的通信层数据结构和基本逻辑,然后基于生成的代码编写具体的业务逻辑,这个时候可能是空就判空,不可能是空就不判空?
trlove
2021-01-27 10:26:02 +08:00
@laminux29 1.不敢苟同您的加强鲁棒性设计。100 个字段出现 100 个状态字段再去分别表示状态,在我看来就是过度设计,滥用设计模式。完全是为了套设计模式而设计,增加了操作流程,延长了操作线。
2.不加状态字段,判断数据本身,如果发生错误,无非就是后端返回了前端没判断,后端没返回(如果前端判断了字段,即使后端出错,前端也不可能出错),那问题就回到了前端的判断问题。所以只需要前端看下代码有无判断就能立马知道是不是后端的错。再退一万步,您认为加了判断状态字段,排查快,不费时费力。但是您忽略了后端操作的错误性。如果上百个字段,您就能保证后端不犯错误忘记改某个字段状态?出现了问题,您能百分百确定是前端没判断 ,还是后端数据改变的不全?不还是得一个个去排查。而且还得是对着数据一个个看,看看哪个数据状态维护错了。您的加强鲁棒性吧问题前置到数据的初始化状态了,排查起来只会更复杂。本身并没有解决您说的犯错误问题。再退十万步,一个系统要想健壮就完全靠拼凑设计模式?就难道没有自测,测试专测,上线前回测,以及灰度?您所说的犯错误的情况在这些测试阶段就能被发现,解决您问题的是测试的流程而不是您的设计模式解决了犯错误的本质。
3.个人理解任何设计模式的流行必然有其合理性。但我认为合理的利用设计模式可以锦上添花,不合理的套用设计模式只会是增加复杂度,并不能实质性解决问题。
lonelymarried
2021-01-27 10:26:31 +08:00
这真那后端没办法,一般如果我的项目,前后端都是我写,就自由多了。这不,后端又出问题了,app 都上线好久了,中途加了个需求,后端就出问题了,昨天反映了,今天还没答复。我是写过 java 后端的,知道这东西也就分分钟的事。没办法,公司的后端就这么搞。自己前后端都学学吧。
GoNtte
2021-01-27 10:26:51 +08:00
第二种好 看返回就知道是数据结构了
0x666666
2021-01-27 10:32:28 +08:00
阿里云官网的做法是:如果 key 的 value 是 null,就不会返回 key 。
第一:不会返回无意义的数据。
第二:省流量(虽然省不了多少)。
第三:如果要后端强制 key 的 value 是 null,要返回一个 key: "" 或 key:[],对于后端来说需要对每个属性都要进行初始化赋空值不说,还要在参数映射完以后,再做一次 null 检查,把 value 是 null 的 key 设空值。这个过程是一个比较麻烦并且没有必要的流程,而且还浪费服务器性能。
第四:和楼上的老哥说的一样,前端不能把命运完全交给后端,自己也要做好空值判断,key 没有的情况。
综上所述,我觉得前端做好对应的判断即可,没必要后端去做这些操作。
0x666666
2021-01-27 10:33:53 +08:00
@Zoomz #106 有的时候不是后端的锅,序列化框架会自动把 value 为 null 的 key 设为空。
Sapp
2021-01-27 10:35:59 +08:00
单个不存在的时候返回 null 、
数组不存在返回空数组

或者你干脆用 typescript,让后端搞个 OpenAPI,写个 node 读取 json 数据自动生成前端接口函数,顺带写上 interface,不就没这个问题了,返回的啥都无所谓,只要他定义好了你这边就有提示
kifile
2021-01-27 10:36:05 +08:00
我会选择第二种,原因是 null 也是一种特殊情况啊,null 和 [] 其实是不等价的,如果业务逻辑中的确是空数组,那返回空数组无可厚非,而如果业务逻辑中应该是 null ,并且使用一些 json 库序列化 null 值,库会帮你删除掉 null 的 key
notejava
2021-01-27 10:37:55 +08:00
前端喜欢第二种,后端喜欢第一种,大家都不想多写几层判断代码
sevenzhou1218
2021-01-27 10:42:56 +08:00
关系好,都不是事,关系不好,死怼。
killerv
2021-01-27 10:43:53 +08:00
我很惊讶那么多说第一种的,B 是个 list,B 的数据没有也只代表 list 为空,不应该没有 B 这个属性,这是两个概念。
举个例子:接口返回的数据表示某个人的一些信息,有个字段是 friends,类型是 list,他可以没有一个 friends,可以是空数组,但是作为人他一定具备 friends 这个属性。
kltt22
2021-01-27 10:46:01 +08:00
你给我个最全的字段,就啥事没有,就怕你现在返回的没有,一会又有了。上次对了个 java,本来说好了是最全的,后来实体类报错了,发现默默的多了几个字段。这玩意后端自己都控制不住的话,还是所有字段都返回吧。
bootvue
2021-01-27 10:54:37 +08:00
凡是为空的 最好都不返回那个字段

按照某些前端的逻辑 B 是集合 返回个空集合 [] , 那 B 要是个 object 返回啥 : null 还是 {} , B 要是 number 返回啥: null 还是 0 完全都是扯淡

不返回意义更明确 前端更好判断 typescript 约束更有意义
asAnotherJack
2021-01-27 10:56:26 +08:00
@kltt22 #132 这种应该放在接口文档里
andyli9449
2021-01-27 10:57:52 +08:00
把问题简化一下,比如一个用户属性。 有 email 字段,且并没有被设置。那么返回的格式应该是 { "email": null } .还是 { "email": ""}; 。API 文档中返回值的定义这个值应该是 string, 但返回 null 就和文档不符。但没有设置,email 值就是""也挺奇怪。比如年龄未设置 该返回时 {"age":null} 还是 {"age": 0} ,API 文档 age 字段肯定应该是数值(Int/Number) 。
est
2021-01-27 10:57:57 +08:00
如果没有的话应该返回: {"A": "", "B": "null"}
cyrbuzz
2021-01-27 11:08:24 +08:00
这个...我怎么觉得返回`{A:""}`其实也不省流量,如果这个接口在一次普通用户访问中只会调用固定的几次,这样前端本来可以写成`response.B[0]`的代码现在要写成`response.B && response.B[0]`,这样不仅没有省流量,还有可能会阻塞首屏加载的嘞= =...
jrtzxh020
2021-01-27 11:11:00 +08:00
@whileFalse 一个?那是一百几十个属性,每个接口都要都不同。String 返回 null Array 也返回 null,前端没有强类型,但是前端变量也有数据类型的好吗
bbao
2021-01-27 11:11:14 +08:00
基本原则:后端的做法好,没有就不传,节省网络传输流量贷款的浪费。

可能一个请求会很大,这样做好处多,前端做校验处理啊;

client -> server 后端在 rpc 到其他服务拿回来的数据,有变化肯定后端已经做好了处理。

前端也要相应的咯。
andyli9449
2021-01-27 11:12:10 +08:00
@killerv friends 没设置返回[]可以,我想知道如果年龄(age)这个属性没有设置应该返回什么 0 或者是 null 吗?

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

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

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

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

© 2021 V2EX