可能是另一场圣战:后端返回的 JSON 的值是只要 String 类型呢,还是各种类型都包括呢?

2018-05-19 15:21:21 +08:00
 winiex

工作中和不同的客户端开发者合作过,有的要求返回的 JSON 统一只包含 String 类型:

{ a: "THYM", b: "107", c: "false" }

而有的则要求数据要表达自己的类型:

{ a: "THYM", b: 107, c: false }

我个人是支持第二种写法的,因为不用再写一堆转 String 和转回类型的代码。大家团队都选择何种方式呢?又是出于何种原因与理由呢?

19201 次点击
所在节点    程序员
161 条回复
h1367500190
2018-05-20 17:30:12 +08:00
@des 我司有个组就是 select * 吐给客户端的,我都是写适配器取出需要的字段并强制转换类型。

我觉得可选字段返回 null 完全没有问题,null 表示没有或不存在,""是实体字符串只不过内容为空而已。

我也赞成而且极力劝说我司后端 enum 用字面量而不是 int,不然返回 1、2、3 之类的数字都不知道是什么鬼,有文档得一直查文档,没文档就呵呵
vicunart
2018-05-20 17:41:43 +08:00
哈哈,你这算个啥...
我这后端特么返的 xml 格式,还特么还用来接微信小程序呢。
sammo
2018-05-20 19:29:41 +08:00
后端传送给前端,肯定要保证网络传送的安全性,肯定要统一。那么其他都不用管,返回值是同一种类型就可以。
第一种 是同一种类型 ( String 类型 )
第二种不是同一种类型 ( 多种类型 ) -- 肯定不选
如果有第三种 是同一种类型 ( int 类型 ) ,那么第一种和第三种还可以看情况考虑一下,当然 为了统一 在同一种类型的基础上 最后还是 string 优先
prasanta
2018-05-20 21:25:49 +08:00
一派胡言,json 就要有 json 的样子
hlwjia
2018-05-20 22:50:15 +08:00
这种问题没啥好争的,从理论上讲是第二种完胜。

但实际情况(技术人员的素质,legacy code 等等)会导致没办法做第二种。

如果是新起项目选第二种是没错的,如果团队的其他人也是这么认为的话

或者你可以在面试的时候就问面试官这些问题


我自己一个人做项目,每次我都提取一些精华放到下一个项目中。
hyyou2010
2018-05-20 23:27:16 +08:00
今天又思考了一下,进一步肯定了 1,主要思路在于分层。

后端 1、2、3 客户端 1、2、3
应用层 1、2、3 应用层 1、2、3
接口层 接口层
+ +
+-----------接口定义---------+


我说说 1 的好处:
1、接口层是 json 的一个最简子集,也即只有字符串,那么可以肯定地说,由于这种简化,使得前后端的接口层都会非常简单稳固。
2、接口层可以由单独的底层小组来开发,完成之后把这个接口层提供给前后端多个业务小组使用,业务小组工作在应用层,应用层才知道 json 的全集,包括 null 和对象等。
3、业务小组极其可能经常修改数据类型,注意,此刻要崩也在业务层崩,不在接口层崩,业务小组调试查 bug 的时候不用找接口层小组。
4、无论应用层怎样改动,无需改动接口层。接口层只有 1 个,应用层是多端多应用。

如上,我认为 1 很好。
hyyou2010
2018-05-20 23:29:28 +08:00
v2ex 这个怎么会帮我删除空格???我的图没法看了。

如下重画:

后端 1、2、3 .......................客户端 1、2、3
应用层 1、2、3 ....................应用层 1、2、3
接口层.................................. 接口层
+-----------接口定义----------------+
pexcn
2018-05-20 23:30:01 +08:00
我上家公司的老项目用 Y/N 表示 true/false (
hyyou2010
2018-05-20 23:35:39 +08:00
软件设计里面有个思路,就是把变和不变的部分独立为不同的模块,层也一样,分隔变和不变的层,我们把永远可以不变的层提取出来作为底层,把经常变动更改的层作为上层。
imn1
2018-05-21 00:24:55 +08:00
补充一个伦理的观点:
第一种全部用 String,不存在不符合标准 /规范的问题,能遵守 json 协议就是符合了
究竟用单类型,还是多类型,其实说到底是看项目的

例如:
我以前一个程序,要判断某股票是否 ST,实际上就是 bool,因为我只关心它的涨跌停是否限制到 5%
但给出数据的那一方会这样理解么,肯定要写清 ST 的细节状态,例如面临退市之类,要作出必要警告

对同一个 json,里面的类型,0/1 究竟是 bool/int/string,只要项目需求不同,各自理解就有差异
所以,并不能说第一种就是要批判的,尤其当 json 的用户很多,众口难调时

类似的「圣战」其实上世纪就有了——
csv 中的数字究竟该不该用双引号
or
csv 中不含分隔符的字符串该不该用双引号
night98
2018-05-21 00:34:53 +08:00
第一种没那么烂吧。

比如现在有个 status 字段表示状态,默认 0 是不锁定,1 为锁定,按照正常来说应该选择 boolean 类型,但是如果要加第三种类型~正在处理,这种的话就很好改了,但是如果是 boolean 类型就很麻烦。
binux
2018-05-21 01:34:50 +08:00
@sammo 后端传给前端的,在网络传送中的明明都是 bytes,怎么就不统一了。你怎么反序列化这个 bytes 和网络传输有个蛋关系。就算你“第一种 是同一种类型 ( String 类型 )” 你还可能在 String 转 Int,转 Bool 的时候挂掉。
iiji86
2018-05-21 08:19:51 +08:00
@night98 但是楼主讨论的是对于布尔值应该转成字符串的"true"、"false"返回,还是直接返回 true、false 的问题,并不是你说的接口设计应不应该使用布尔值的问题啊
startar
2018-05-21 09:04:48 +08:00
补充一个非用字符串不可的 case,传递 64 位整数
lockelee
2018-05-21 09:12:16 +08:00
要是外包项目他爱怎么搞怎么搞,能交付别找你麻烦就行。
要是产品类的,长期维护的项目,根本不用圣战,肯定第二种啊=、=
koalli
2018-05-21 09:44:07 +08:00
我和 php 服务端对接的时候无数次遇到商量好的给数组结果给过来一个 key-value 表的情况...
在我们的客户端里,这两种不同类型的结构在遍历、取值上由于性能差异需要调用不同的方法,约定好格式其实本质上是为了出问题的时候方便追责(甩锅)。
楼上有个兄 dei 说得对,客户端永远都是不相信服务端的。因为你不知道服务端线上部署后会不会出幺蛾子返回莫名其妙的数据,比如某台服务器出错了其他通过这台服务器获取的数据返回给客户端就出了问题,甚至还会有第三方的服务器返回的结果有问题,实际情况往往更复杂。
另外防御性的代码写多了分支也就多了,测试的路径覆盖不够充分的话就容易埋雷出了问题难以调试,部分语言里 if-else 分支多了甚至会影响性能,所以客户端服务端双方需要商量一个统一个规则,最好当然是使用 protobuf 之类的工具来做解析。
skyfore
2018-05-21 09:58:08 +08:00
前后端分离 + 严格的定义标准 + 清晰的 API
不就完事了吗?非要这样来搞什么兼容
USNaWen
2018-05-21 10:11:51 +08:00
肯定第二种啊,要是 json 里有数组和嵌套的 obj 第一个怎么办?再解析一次?
严格类型后端检查长期只有好处没有坏处。
ragnaroks
2018-05-21 10:23:03 +08:00
//因为接口方技术低劣,这里需要手动对接收的数据进行预处理,严重影响了开发效率
Code Here

等 code review 阶段老大发飙
Lanke0
2018-05-21 10:28:09 +08:00
看情况吧,一般是第一种。不是你想怎么玩就怎么玩,而是大家要沟通好

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

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

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

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

© 2021 V2EX