V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
wojfsdj
V2EX  ›  程序员

大家前后端规范是怎么制定的呢?

  •  
  •   wojfsdj · 2018-04-11 09:08:03 +08:00 · 12038 次点击
    这是一个创建于 2452 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如使用 JSON 格式,那么怎么有效的表示空数据呢? 空字符串是返回 null, 还是"" ,数字是返回 null,还是 0 呢,集合是[],还是 null?

    其他方面还有哪些是需要前后端一些协商规范的呢?希望大家指点一二

    68 条回复    2018-04-11 21:05:06 +08:00
    gbc123456
        1
    gbc123456  
       2018-04-11 09:18:11 +08:00
    我回复的时候,点击:40 次,没人回答你啊?

    那我讲讲我这里的规范,空字符串 定义为 "",数字定义为 0 , 集合你应该猜到了,当然是 []

    什么?你问我为啥?
    因为,数据做签名处理, AES 加密什么的,比较好做,不会出现一些解密失败的情况

    以上就是看看,觉得有问题请指出,谢谢
    silencefent
        2
    silencefent  
       2018-04-11 09:18:45 +08:00   ❤️ 1
    口口相传
    ChefIsAwesome
        3
    ChefIsAwesome  
       2018-04-11 09:21:51 +08:00   ❤️ 10
    “你这地方怎么挂了?”
    “我看看…因为你回了个 null ”
    “你不能判断下吗?”
    “你不能判断下吗?”
    RainFinder
        4
    RainFinder  
       2018-04-11 09:23:40 +08:00   ❤️ 3
    后端定好,前端看着办
    leeyom
        5
    leeyom  
       2018-04-11 09:25:49 +08:00   ❤️ 1
    可以看看阿里巴巴的[《 Java 开发手册》]( https://github.com/alibaba/p3c),里面讲的很详细。
    sagaxu
        6
    sagaxu  
       2018-04-11 09:29:17 +08:00 via Android
    尽量用 null 表示空值,并且序列化时忽略 null 字段
    v2410117
        7
    v2410117  
       2018-04-11 09:31:20 +08:00
    最讨厌的就是后端返回 null,文档全写的是 String 类型,到时候有数据了,什么 number、bool、对象、集合都出来了,程序就到处都崩瞎卡拉卡(别问我为啥不和后台沟通),二手私活,后端也是外包的!找不到人!所以现在都是数据请求回来自己先判断一波,把数据处理好了再用,一个不靠谱的后端的随时都可能在数据中埋雷让程序崩溃!(菜鸟个人观点,后端大佬勿喷,理性分析)
    wizardoz
        8
    wizardoz  
       2018-04-11 09:32:15 +08:00   ❤️ 2
    就数字来说,0 和 null 是两种含义,字符串的 null 和""、数组[]和 null 同理。
    你说用 0 代表空数据,那你用什么代表 0 ?
    yimity
        9
    yimity  
       2018-04-11 09:33:12 +08:00
    空字符串定义为 "",数字定义为 0 , 集合你应该猜到了,当然是 []
    littleshy
        10
    littleshy  
       2018-04-11 09:33:16 +08:00
    除集合外,其他可为 null。
    wojfsdj
        11
    wojfsdj  
    OP
       2018-04-11 09:34:52 +08:00
    @leeyom 之前看过,但是好像没有找到这方面的规范
    wojfsdj
        12
    wojfsdj  
    OP
       2018-04-11 09:35:48 +08:00
    @v2410117 o(︶︿︶)o 那你可能判断的类型就有点多了
    wojfsdj
        13
    wojfsdj  
    OP
       2018-04-11 09:36:36 +08:00
    @gbc123456 数字空定义为 0,那如果是想表示 0 怎么办呢?
    v2410117
        14
    v2410117  
       2018-04-11 09:41:42 +08:00
    @wojfsdj 遇到这种情况了能咋办呢,难不成找到后端让他改,不现实吧,反正都是在基类里判断,也不多吧,无非就是判断下集合和对象,其他的统一转成 String 处理了。
    queuey
        15
    queuey  
       2018-04-11 09:51:53 +08:00
    瞎几把搞的 json 格式能把人坑死
    night98
        16
    night98  
       2018-04-11 09:57:45 +08:00 via Android
    字符串 null,数字 null,数组或集合[],其他待定,后端确定就好了,前端跟着后端规范走
    netlxl
        17
    netlxl  
       2018-04-11 09:58:23 +08:00 via Android   ❤️ 1
    json 是序列成字符串的简单对象,支持 null。所以,能用 null 的就别做无谓的转换。
    ""显然不可取,除非它就表示空字符串而不是 null (另外既然前后端分离了,那后端自然也不需要考虑 null 显示成空白的设计了。)。
    数字最好也是 null,但用 0 也可以,取决与前后端的协商。不过建议还是用 null,虽然这需要前端反序列化后的 JavaScript 对象中,这个字段的类型不能是基本类型,至少也得是 Numbei 对象。
    数组应该没啥说了,null 和[]在绝大多数情况下都是表示一个含义。
    resturlaub
        18
    resturlaub  
       2018-04-11 09:58:41 +08:00
    自己去看代码啊
    BearD01001
        19
    BearD01001  
       2018-04-11 10:00:06 +08:00 via iPhone
    空字符串定义为 "",数字我偏向于定义为 null,因为有时候确实需要区分 0 数据与无数据,集合当然是 []。最烦没数据都返回 null 的,拿到数据用的时候都要小心翼翼的,特别是多维集合,每一层每一个数据用之前都要 if 判断一遍,烦死了!
    h1367500190
        20
    h1367500190  
       2018-04-11 10:02:49 +08:00
    @ChefIsAwesome 和我司后端一个卵样,返回的数据什么类型的都有
    BearD01001
        21
    BearD01001  
       2018-04-11 10:02:54 +08:00 via iPhone
    @v2410117 我一般遇到这种情况都会直接在群里怼后端,文档定义不规范开发成品不规范,接口对接起来烦的一批!🙂
    BearD01001
        22
    BearD01001  
       2018-04-11 10:04:43 +08:00 via iPhone
    @v2410117 不过我们公司接口定义文档是由需求人员写的,群里吼出来!让需求跟接口开发内撕去!
    janus77
        23
    janus77  
       2018-04-11 10:09:10 +08:00
    通过与测试撕逼的经验总结,不能靠规范,要靠自己
    我认为「你不能判断下吗」暴露的其实是撒手不管的无责任感
    v2410117
        24
    v2410117  
       2018-04-11 10:16:46 +08:00
    @BearD01001 自家的文档还是很规范,专人负责,后端也不会这样搞,关键是之前弄的都是些外包,要的是速度,后端也啥都不管,文档乱写,你怼他,他就觉得“你自己加个 if 判断一下不就完事了”,感觉这事根本就不是后端的事,就是我们前台偷懒不想搞才叫他弄似的,后端都是大佬,觉得我们就是画界面的(个例,不范围攻击,我只表达我遇到的个人情况,勿喷)
    stach
        25
    stach  
       2018-04-11 10:18:22 +08:00
    我是后端,我的原则是:
    数据库表的设计,除了 datetime 可以为 null,都采用默认值,不允许为 null ;
    联表查询的时候,确实没有数据,那就是 null ;
    在使用 id 的时候,因为 id 从 0 开始,如果要用一个数字表示全部,就用 -1 或者 null 来表示。

    总结来说:数据库尽量不要有 null 的出现,程序中或者应用场景需要就特别定义和处理它。
    mhycy
        26
    mhycy  
       2018-04-11 10:21:35 +08:00
    看来楼上各位没碰上连 HTTP 请求参数在内都是拼接出来的后端程序员。。
    还强制要求按顺序拼回去验证(然而拼接并没有按规范转义)
    bhaltair
        27
    bhaltair  
       2018-04-11 10:27:15 +08:00
    空值返回''
    netlxl
        28
    netlxl  
       2018-04-11 10:28:11 +08:00
    @gbc123456 再定义个序列化规范:要么序列化所有字段,要么都不序列化 null,举手就能解决掉签名的问题,你非要搞这么容易出错的方案。
    @v2410117 如果前端不参与接口定义,就是这种结果。前后端分离开发,最合理的接口设计方式时,需求出需求层面数据模型->后端出设计层面数据模型->前端透彻理解需求层面数据模型并了解设计层面数据模型->前端定义接口->后端找刺->回归定义->前后端同时开发->前后端单独单元测试(前端先用测试桩模拟接口)->继承测试。两个重点:前端定义接口;前端也要了解后台的数据模型。
    @BearD01001 建议你去看看阿里 java 开发规范。为了解耦、主动防御、减少重复判断,是否为 null 的判断,应该是消费方 /调用方处理,而不是生产方 /被调用方处理。这个规范不限于接口定义,而是内部编码也要遵守的。
    netlxl
        29
    netlxl  
       2018-04-11 10:30:26 +08:00
    @stach 你应该没用过 Hibernate 或者的 ORM 框架,说实话,我最讨厌的就是后端还跟数据库耦合。
    stach
        30
    stach  
       2018-04-11 10:33:14 +08:00
    @netlxl 没有用过 java 的 ORM,用过很多其他语言的,老兄有什么好的设计直接说,说的太抽象,看不懂。
    zjp
        31
    zjp  
       2018-04-11 10:33:28 +08:00 via Android
    @stach 数据库中不推荐使用 null 是因为对 null 值的优化有限吧。
    代码层面没有这个问题,还是按着语义来选择 null 或者空字符串。对于集合,Efficient Java 推荐用空集合而不是 null
    stach
        32
    stach  
       2018-04-11 10:34:00 +08:00
    @netlxl 你直接说每种字段类型怎么定义就可以了,这个和 ORM 没有任何关系。
    stach
        33
    stach  
       2018-04-11 10:36:49 +08:00
    @zjp null 本身就是个不稳定状态,容易出状况,对于可能出现 null 的都要判断的。
    ChefIsAwesome
        34
    ChefIsAwesome  
       2018-04-11 10:37:31 +08:00
    既然后端会验证,会报错,那么前端还要验证提交的数据吗?
    前端需要做个列表页,后端会只把 id 全取出来,再让前端一个一个取详情吗?
    不是谁干的活多谁干的活少的问题,也不是怎么设计,能让你代码结构不那么恶心的问题。技术是拿来做产品的,产品是拿来服务用户的。牺牲用户体验的东西都是瞎搞。
    stach
        35
    stach  
       2018-04-11 10:37:35 +08:00
    @zjp 比如 golang 里面的类型都会强制默认值,我是很喜欢的。
    stach
        36
    stach  
       2018-04-11 10:39:57 +08:00
    @ChefIsAwesome 该做验证的不能省事,前后端都得做。
    列表页你说的这种,我都是把数据加工好给前端的。
    jinzhe
        37
    jinzhe  
       2018-04-11 10:54:35 +08:00
    作为前端超不喜欢后端给 null,这样渲染的时候还要一个个判断。
    v2410117
        38
    v2410117  
       2018-04-11 10:54:43 +08:00
    @netlxl 感谢,学习了!
    netlxl
        39
    netlxl  
       2018-04-11 11:00:16 +08:00
    @stach 要说理论都很抽象,我就举个 Java Hibernate 的例子吧。
    Java 对象:
    class Entity{
    Integer intValue = null;
    Integer intValueHasDefault = 2;
    String stringValue = null;
    Decimal decimalValue = null;
    Boolean isSuccess = false;
    Boolean isHasError = true;
    }
    默认映射方式下的数据库表:
    create table entity(
    int_value int default null,
    int_value_has_default int default 2,
    string_value varchar(255) default null,
    decimal_value number default null,
    is_success bit/tinyint default 0,
    is_has_error bit/tinyint default 1,
    )

    java 对象这边,默认值是否是 null,完全取决于业务的需要,不用考虑数据库。查询更新数据操作的都是 Java 对象,不是 SQL 语句。
    数据库这边,如果 DBA 确定性能上不适合用 null,那么修改数据库和映射关系。

    上面这种设计方式,必须要完整 ORM (本例中是 Hibernate )的支持,在国内还不是主流。国内用得多的是半 ORM ( MyBatis ),还没有解开业务开发和数据库开发。
    netlxl
        40
    netlxl  
       2018-04-11 11:04:26 +08:00
    @jinzhe 渲染时候的 null 判断应该交给前端框架处理。
    oswuhan
        41
    oswuhan  
       2018-04-11 11:11:14 +08:00
    制定与实施规范的权责必须分离,开发者在任意时刻不能同时担任规范制定者与执行者双重角色。

    具体实践的时候,可以引入类似于 http://yapi.demo.qunar.com/这样的工具。
    wojfsdj
        42
    wojfsdj  
    OP
       2018-04-11 11:13:42 +08:00
    @netlxl 清晰很多了。对于 Java 而言,是否 DTO,或者请求的 Param 也用 Intger 等包装类来接受对应的参数了,这样才能有 null 了
    Zzde
        43
    Zzde  
       2018-04-11 11:22:08 +08:00 via iPhone
    None null 混着 傻傻分不清
    netlxl
        44
    netlxl  
       2018-04-11 11:24:14 +08:00
    @wojfsdj 作为数据对象的 pojo 最好都用包装类。有个极端说法是:除非是方法内部使用的变量,都要用包装类。另外只有 Boolean 类型的布尔值,可以命名为 isXXX,基本 boolean 类型布尔值,是不能名名称 isXXX 的。
    lsls931011
        45
    lsls931011  
       2018-04-11 11:28:17 +08:00
    @ChefIsAwesome 验证这事情, 前后端都要进行,这是两道防线。 而且前端验证可以减缓服务器压力,提升服务器的并发。后端验证是为了处理那些非常规请求
    Mutoo
        46
    Mutoo  
       2018-04-11 11:32:44 +08:00
    用 GraphQL 多省事,前端想怎么整就怎么整,不需要后端插手。
    stach
        47
    stach  
       2018-04-11 12:11:42 +08:00
    @netlxl 所以你的设计其实是偏向于用 null 的,不去限制 null 的产生,我的原则是把 null 统统干掉。
    你假想不管是前端,还是后端,都有成熟的框架,都能帮你去处理 null 的判断问题。
    我假想的是不管有没有框架,纯 sql 也好,ORM 也好,都能很稳定,让数据可预期,而不是不确定,有歧义。
    gamexg
        48
    gamexg  
       2018-04-11 12:24:03 +08:00 via Android
    坚决抵制 null。
    akira
        49
    akira  
       2018-04-11 12:29:49 +08:00
    只要都遵循一个规范,都可以
    v2chou
        50
    v2chou  
       2018-04-11 12:37:21 +08:00
    我们后端看他心情返回 什么样的都有 '' [] null 1 '2' 要什么有什么
    v2chou
        51
    v2chou  
       2018-04-11 12:39:46 +08:00
    我是日了🐶了
    lamada
        52
    lamada  
       2018-04-11 12:57:54 +08:00
    建议前端自己写一个校验 response 的规则
    faceRollingKB
        53
    faceRollingKB  
       2018-04-11 14:39:43 +08:00
    有些容易被踩的坑规范下,免得出问题老得给新人讲
    有些有争议的做法规范下,免得老得说服别人怎么写
    tjsdtc
        54
    tjsdtc  
       2018-04-11 14:42:20 +08:00
    只要规范统一就行,比如空数组不要一会返回[]一会返回 null 就行
    liyj144
        55
    liyj144  
       2018-04-11 14:59:58 +08:00
    后端返回 "", 0, []. 不过前端最好也都校验一把。对于嵌套较深的 Object,后端很容易漏处理。
    silhouette
        56
    silhouette  
       2018-04-11 15:13:06 +08:00 via Android
    字符串为空就不要 null 而是空字符串,其他的该 Null 就 Null
    eloah
        57
    eloah  
       2018-04-11 15:16:44 +08:00
    我本来想过来吐槽一下我们公司后台什么规范都没有,大家写代码都随心所欲的
    然后看了一下描述的 JSON 的问题,感觉我们公司还没这么不规范
    Doge
    colorwin
        58
    colorwin  
       2018-04-11 16:47:37 +08:00
    我是前端,我们的后端 {} 为空的时候返回 null, 他说返回 {} 这样很麻烦,他用的是 Java,请问是这样吗?
    lovedebug
        59
    lovedebug  
       2018-04-11 17:56:50 +08:00
    全都字符串化,不用扯皮了。
    wojfsdj
        60
    wojfsdj  
    OP
       2018-04-11 17:59:29 +08:00
    @colorwin 也不麻烦呢,就初始化一下
    shuizhengqi
        61
    shuizhengqi  
       2018-04-11 18:10:13 +08:00
    厉害了,我就没有这种烦恼,因为前后端都是我
    repus911
        62
    repus911  
       2018-04-11 18:54:09 +08:00
    swagger
    repus911
        63
    repus911  
       2018-04-11 18:58:40 +08:00
    安利 swagger 吧,统一接口定义,接口校验,接口文件生产,在线接口文档,省不少事情
    zpf124
        64
    zpf124  
       2018-04-11 19:07:51 +08:00
    拍脑袋定 (#滑稽)



    说正经的

    数组 对象 之类的尽量不使用 null,[]或者{}表示。

    其他类型的,则 统一标准,null 或者直接不存在这个属性的 key,我更倾向于直接不包含这个 key。
    string 也类似,只不过统一的选择除了 null 和 undefined 还有个 ""。
    zpf124
        65
    zpf124  
       2018-04-11 19:08:48 +08:00
    漏了一个字。

    数组 对象 之类的尽量不使用 null,用 []或者{}表示。
    xiangyuecn
        66
    xiangyuecn  
       2018-04-11 19:45:04 +08:00
    比如 java:int 类型的变量没法手写赋值为 null,所以接口返回的数字类型就尽量别扯 null 了,不过有人喜欢当 object 处理,比如我

    null 这个玩意在数据库最好给默认值妥妥的,字符串"",数字 0,日期给默认值 1800-01-01/2100-01-01

    前端其实比后端简单多了,js 的||运算符用合理了,管后端传的什么炸弹都全部通吃 (滑稽
    fcoolish
        67
    fcoolish  
       2018-04-11 19:48:57 +08:00
    你们天天不得开进度会嘛
    wojfsdj
        68
    wojfsdj  
    OP
       2018-04-11 21:05:06 +08:00
    @xiangyuecn 可以用包装类 嘿嘿 →_→
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5014 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 09:40 · PVG 17:40 · LAX 01:40 · JFK 04:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.