可能是另一场圣战:后端返回的 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 和转回类型的代码。大家团队都选择何种方式呢?又是出于何种原因与理由呢?

19130 次点击
所在节点    程序员
161 条回复
imn1
2018-05-19 19:39:22 +08:00
@ZiLong
例如一个项目,有 ABC 多个模块,它们之间都是通过一种二维数组传递数据的
这时,因为需要,从外部获取一个源数据,而它是由提供方决定格式的(例如 json ),项目组无法决定其格式或类型
这时就需要用一个 D 模块处理,转换为二维数组,交给 ABC 使用
正因为数据源是外部,往往 D 模块里面要加容错代码,如果类型复杂,容错和转换工作就多很多,只是 string 就简单了

如果数据源头有多个,可变(例如合作方变更),预处理就很必要了,没理由改变原来项目的 ABC 的

这种情况以前见得多了,曾见过一个糟糕的项目,合作方改了数据格式,项目就要重写……
hyyou2010
2018-05-19 20:00:02 +08:00
差异可能在于两种方式在客户端的出错处理位置不同,难度不同

考虑到语言特性,数值边界,那么 api 接口最好很直白,很傻,并排除任何语言特性的影响

过去的项目是 2,但在数据类型上趟过太多痛苦的坑,考虑以后试试 1
Him
2018-05-19 20:13:46 +08:00
@janxin 不走测试环境测试直接把修改上线,这样的团队连基本的流程都没有了……
hyyou2010
2018-05-19 20:15:56 +08:00
说几个接口的坑,不一定对,供参考:
1、数组里面必定同类型,不然强类型语言处理起来麻烦
2、不要用 bool,而用整型 0、1,不然不好扩展
3、不要有 null 或别的空类型定义,整型的话用-1 表示没有,字符串用“”或其他特别串表示没有
GreenVine
2018-05-19 20:17:28 +08:00
@scriptB0y 看上去是 Certificate pinning 防止中间人的
iwtbauh
2018-05-19 20:39:42 +08:00
@scriptB0y 这个和话题关系不大啊,写死可能带来巨大安全好处。公钥钉扎( public key pinning )了解一下。Google 就曾经将自己域名的证书写死在 chrome 里,也是因为这种操作,某个 CA 的二级私自签发 google 域的证书(哪家不用我说了吧,就是这事之后被 Mozilla 和 Google 拉黑的那家),但 chrome 避免了被中间人攻击。同时使用 chrome 的用户自动将事件报告 Google,并公之于众。

钉扎是出于安全方面的考虑,但的却会带来你说的那种不易换证书的问题,但这要看怎么权衡了。
Hardrain
2018-05-19 20:46:07 +08:00
boolean 也要变成 str?

有的语言似乎不能直接把 str 转回 boolean ……
prolic
2018-05-19 20:46:52 +08:00
一直在用第一种,流程中备不住哪个用 php 的写的菜一点,就 int string 混用了,还不如从头到尾强转 string 还能统一一下
Axurez
2018-05-19 20:50:02 +08:00
居然还有选 1 的,今天也是长见识了。
hxy91819
2018-05-19 20:51:46 +08:00
我们团队是用第二种方案,甚至服务端有些不合规范的字段,客户端会要求按类型规范整理。
Axurez
2018-05-19 20:57:19 +08:00
敢问选 1 了之后,如果字段是一个对象怎么办?比如

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

按照某些理论,就应该把对象转字符串,因为对象不靠谱:

```
{ "a": "{ \"b\": \"107\", \"c\": \"false\" }" }
```

那么问题来了,你这个根对象不也是个对象?难到你也要包成字符串?


```
"{ \"a\": \"{ \\\"b\\\": \\\"107\\\", \\\"c\\\": \\\"false\\\" }\" }"
```

???那你为啥还要用 JSON 呢?为啥不自己发明一种格式?
peterpark
2018-05-19 21:02:16 +08:00
偶遇聂帅^_^
huclengyue
2018-05-19 21:09:24 +08:00
@Death @Death @airyland @wxsm @winiex 你去问问 iOS 开发者就知道了,
huclengyue
2018-05-19 21:10:56 +08:00
@huclengyue 当然如果只是前端 js 的话,第二种效率更高
huclengyue
2018-05-19 21:12:37 +08:00
@airyland 并不是。。。
huclengyue
2018-05-19 21:14:01 +08:00
@isbase 你开发和 android 或者 iOS 应用试试,就知道为什么会是第一种了
hyyou2010
2018-05-19 21:15:57 +08:00
@Axurez

我的观点是,接口定义上不能有对象这个概念,接口必须是字面的,plain 的。
我前面写了点个人坑,其中不要 null 或空定义就是针对“对象”的。
huclengyue
2018-05-19 21:16:42 +08:00
@Eoss 那你让 iOS 怎么判断 true false ?? iOS 是 yes no
huclengyue
2018-05-19 21:21:53 +08:00
@Axurez 所以为什么要在接口中传递对象?
xiaottt
2018-05-19 21:26:03 +08:00
反正我们合作过的 partner 的文档,都是要求第一种

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

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

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

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

© 2021 V2EX