V2EX 首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

有没有这样一个 lib,可以帮 js 前端“清理”后台 api 返回的数据结构?

  •  1
     
  •   wxsm · 67 天前 · 2585 次点击
    这是一个创建于 67 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如说,按照约定后台应该返回这样的一个数据结构:

    {
      a: {
        b: [] // 某数组
      },
      c: '某字符串'
    }
    
    

    但是有时候事与愿违,团队开发者一多,后台往往会返回缺斤少两或者奇怪的东西,导致错误,比如

    {
      a: null,
      c: null
    }
    
    

    或者:

    {
      a: {
        b: null
      }
    }
    
    

    我知道可以通过逐个字段判空来解决,但这太麻烦了,而且一不小心就漏掉了什么地方。有没有一种工具,可以对这样的数据按照约定结构进行补全呢?

    比如:

    • 数组默认为 []
    • 对象默认为 {}
    • 字符串默认为空字符串
    • 数字默认为 0
    50 回复  |  直到 2017-12-21 11:43:55 +08:00
        1
    muziyue   67 天前   ♥ 5
    想法不错,不过遇到这种情况找后端打一架比较管用
        2
    orancho   67 天前
    Protobuf 请。
        3
    264768502   67 天前 via iPad
        4
    LancerComet   67 天前   ♥ 1
    看了上文,实际上如果接口很多业务很个性,为了确保类型安全还是要写很多业务相关的过滤器,目前看来并没有什么特别好的偷懒方法.

    在下所在项目目前的实践是为关键服务的接口写过滤器 + TS Definition,并会在代码审核时检查,说白了就是这个任务一点没省,只不过是平均了罢了.

    期待有更好的偷懒实践.
        5
    wxsm   67 天前
    @muziyue 打得了现任打不了下一任,自己不做处理总会有被坑的一天。

    @orancho 这个好像是新的数据交换结构,新项目可以考虑,可是现有的基于 JSON 的项目怎么搞?

    @264768502 好像不是我想要的东西。
        6
    crysislinux   67 天前   ♥ 3
    json schema 校验,放在后端的出口就好了,不符合 schema 的就直接报错让后端改,不然你补全了有什么用,你补的了代码补不了逻辑。
        7
    orancho   67 天前
    @wxsm

    现有项目的话只能靠沟通和管理了,当然你也可以试着迁移一下。
    P.S. 我司自从尝了 protobuf 的甜头之后大部分项目都迁移了过去。
        8
    zjsxwc   67 天前
    必须要前后端都有一个约定才能解决楼主问题,不然缺斤少两的情况下,也无法判断出缺的那个字段是补成[]还是{}还是""还是 0
        9
    zjsxwc   67 天前   ♥ 1
    2 个办法:

    1. 类似 protobuf 辅助在代码上统一,*约定*通过编写 protobuf 消息文件来指定, 要改原来的代码

    2. 用中间转发网关,*约定*通过在这个中间网关里通过图形界面配置,我记得有开源的
        10
    maemual   67 天前 via Android
    我觉得在后端数据无法通过工具约束的情况下,遇到这种错误的数据直接报错更好一点。否则用默认值,当作正常数据再写回到后端的话,以后坑更大。
        11
    Torpedo   67 天前   ♥ 1
    之前的项目就是这样。服务代理了很多接口,接口文档都没有。他们的数据总是不稳定。
    其实我理解这个问题有两点:
    1.不管什么库,按照你说的那么做都要把数据结构描述一遍。
    2.找出不符合的情况不难,那么我一个一个写呢。但是比较大的问题是:这么多字段,每个出问题了都是一个异常处理逻辑。

    基于以上两点,1 明显应该是大家约定的,但是却约定不好。2 一个个写太多。
    我们用了 react,所以比较好的方法是用 react16 的 componentDidCatch,封了一个高阶组件来统一处理页面模块出错。

    本来这问题就是数据问题,哪个数据问题就修复哪个数据就行了。只是前端这里处理,不因为他们的数据问题让整个页面挂掉就可以了
        12
    cenqingbo   67 天前
    @crysislinux 作者贴出来的错误的 null 返回也属于正确的 json shema 吧
        13
    Terry05   67 天前
    没啥好偷懒的,一个个节点去判断
        14
    will0404   67 天前 via iPhone
    这绝对是后端的锅啊,为什么要前端做?在 api 输出的地方做类型检查就好了,前端加个 lib 增加多少流量考虑过吗
        15
    wxsm   67 天前 via iPhone
    @zjsxwc 你说的这种“网关”其实不切实际。这样一来架构会变得极其脆弱。

    @maemual 主要是用来显示的这一块,不往回发。一报错测试马上就找到前端来了,各种背锅。

    @Torpedo 你这个办法看起来不错,我这边也是 RN,明天试一下。谢谢。
        16
    wxsm   67 天前 via iPhone
    @will0404 组织已经决定了,这个锅就 tm 前端来背。
        17
    sensui7   67 天前   ♥ 4
    参考这个视频:
        18
    jzhang   67 天前   ♥ 1
        19
    isbase   67 天前
    @Torpedo 我觉得如果是后端数据的问题,那就该正常抛出错误让页面挂掉,否则你 catch 了错误继续运行下去可能会导致更严重的问题

    @wxsm 平时写代码的时候可以多用 ES6 的函数参数默认值
        20
    wanganjun   67 天前 via iPhone
    为啥没人说 graphql
        21
    janxin   66 天前
    @wanganjun 因为 graphql 没有什么收益,除了前端偷懒以外
        22
    kaneg   66 天前 via iPhone
    把后端返回的 json 合并到定义的默认 json,是不是就得到楼主想要的结果了?
        23
    aegisho   66 天前 via Android
    1.明确规范,出 bug 算到后端的责任
    2.老老实实写防御性代码
    3.考虑类似 json schema 校验补全
    4. 我能(要)打十个
        24
    wxsm   66 天前 via iPhone
    @jzhang 看了一圈文档,貌似没有发现对缺失值的处理办法?

    @isbase 默认值只能解决很小一部分的问题。通常数据都会有深层次的结构。

    @kaneg 同上。
        25
    vinceguo   66 天前 via Android
    楼上有人提到 protobuf,那我就顺便说一下 thrift 吧。类似的东西
        26
    RorschachZZZ   66 天前
    这就是参数规范化的重要性。
        27
    Obelly   66 天前
    一种“天才”的解决方案,将所有非数字全部格式化成字符串,要处理数据再另行处理字符串文本内容……
        28
    Mutoo   66 天前
    1) json schema
    2) lodash _.get(obj, path, default) 方法
    https://lodash.com/docs/4.17.4#get

    var object = { 'a': [{ 'b': { 'c': 3 } }] };

    _.get(object, 'a[0].b.c');
    // => 3

    _.get(object, ['a', '0', 'b', 'c']);
    // => 3

    _.get(object, 'a.b.c', 'default');
    // => 'default'
        29
    crysislinux   66 天前
    @cenqingbo 不全是,当然 schema 也不能保证逻辑正确,但是能保证该在的 fields 都在,类型都对
        30
    wxsm   66 天前 via iPhone
    @Mutoo 这种实际上就是逐个字段判断了。而且这个 defalt 有局限性,处理的只是 key 不存在的情况。万一存在而且是 null,那还是会有问题。还得再加判断。麻烦得很。
        31
    wotemelon   66 天前   ♥ 1
        32
    bfbd   66 天前
    Object.assign(retData, defaultData)
        33
    bfbd   66 天前
    写反了,应该是:newData = Object.assign({...defaultData}, retData)
        34
    vghdjgh   66 天前 via Android
    这种情况的解决方案就是接口文档中也提供一份语言无关的 protobuf 或 json schema 文件,然后收到数据时做验证
    如果用 typescript,我用 https://github.com/plantain-00/types-as-schema 通过 types 生成 json schema 或 protobuf 文件
        35
    mougua   66 天前
    这种情况,我一般是买把菜刀放桌子上,然后叫后端同学来谈谈接口~~~~
        36
    YMB   66 天前
    我觉得开发 API,第一件事就是定义接口规范,第二是授权机制。
    接口规范可以用一个类封装一下,授权机制可以用中间件过滤一下。
    然后写业务逻辑,基本没什么问题。
        37
    th00000   66 天前
    我完全同意一楼的看法 出现这种情况直接把后端打残比较好
        38
    evolify   66 天前
    和楼主一样的情况。而且更离谱的是,对于为空 l 的字段,他们直接 ignore 了,说是什么发的数据少一点快一点,简直是扯淡的优化。之前好好的,这么一搞,我前端一堆 undefined. 现在我的做法是在接收后台数据时,手动重新赋值,所有字段都用我习惯的命名方式,不然他后台又一改字段或者说两个地方字段名不一致,那就 GG 了。
        39
    justfindu   66 天前
    这个完全不能做呀, 智能化了解你的接口数据, 比如你的示例 给的 b:null, 那我应该给 b 一个{} 还是一个[] 还是'' . 你会说你可以通过配置来确定某个接口给的数据是什么, 那为什么不直接跟后端沟通? 这才是正确的出路啊...不规范的接口以后都是痛. 难道你 APP 也要一个筛选?
        40
    wxsm   66 天前
    @wotemelon 这个有这么点意思,好像是我想要的东西。谢谢!
        41
    wxsm   66 天前
    @justfindu 因为前端对数据的类型是有“预期”的(按照约定)。比如说正常来说数组都是用来遍历的,但是后台就返回了个 null,导致遍历失败报错。如果我按照“预期”把它变成一个 [],那不就解决了。团队开发者一多,沟通成本很高,反正我提过很多次了,根本没人鸟我。
        42
    li746224   66 天前
    graphql 吧,虽然觉得前端收益大,后端搞起来麻烦
        43
    v2chou   66 天前
    我们后台就是这样
        44
    leemove   66 天前
    哎呀 现在每一个请求我都会 catch.最要命的的是超时.
        45
    justfindu   66 天前
    @wxsm 所以我说你要通过配置预期来格式化每一个接口, 接口数据一多, 你就死了. 虽然我是后端, 但是这锅明显要甩给后端. 你就不管, 只要不符合格式, catch 到错误, 你就提示数据无法获取 哈哈哈哈
        46
    ChristopherWu   66 天前
    这种一般后端做,如上面同学说的 json schema,不但验证 request,给前端 response 也验证了。
    后端不上只能打一架了
        47
    yuxuan   66 天前
    明显后端的锅 楼主要强势一些 加 lib 是在牺牲前端性能来做
        48
    kenshinhu   66 天前
    有责任的后端都会把这个解决的
        49
    denano   66 天前
    和后端定好数据结构,给出 api 文档当然是最好的了,还有自己前端写个函数判断下返回值结构咯
        50
    paradoxs   66 天前
    我们公司的话,大概 这个样子
    {
    result: 000000 成功 999999 失败 22222 某某错误
    msg:
    data :
    }
    DigitalOcean
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   2014 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.0 · 75ms · UTC 13:55 · PVG 21:55 · LAX 05:55 · JFK 08:55
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1