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

怎么看待请求参数 JSON 数据包里再包 JSON 数据

  •  1
     
  •   Aluhao · 331 天前 · 6218 次点击
    这是一个创建于 331 天前的主题,其中的信息可能已经有所发展或是发生改变。
    请求数据结构如下:

    {"id":"100","time":1666320790000,"validate":"cc2ac65f816faf49f7e","data":"{\"reqid\":\"\",\"taskid\":\"\",\"sid\":\"B464AA\",\"atuser\":null,\"content\":{\"type\":1,\"text\":\"{\\\"text\\\":\\\"000\\\"}\"}}"}

    这样的设计大家有什么看法?
    64 条回复    2022-10-29 07:10:12 +08:00
    xtinput
        1
    xtinput  
       331 天前
    没毛病
    vagusss
        2
    vagusss  
       331 天前
    这是把 data 里的数据结构序列化成字符串了吧.
    chendy
        3
    chendy  
       331 天前
    目测接口会取 json 里面的 json 单独再做一次反序列化
    没啥看法,调就行了,有空就简单封装一下让这层在客户端不可见就是
    wangtian2020
        4
    wangtian2020  
       331 天前   ❤️ 8
    别提啥设计了,之前帮领导朋友去他们公司干几天活,他们公司技术部长亲自下场写代码,返回的接口全是我要 JSON.parse 一遍的字符串 JSON 。大胆一点,就是菜!
    liyang5945
        5
    liyang5945  
       331 天前   ❤️ 1
    formData 里套 json 的我都见过
    infun
        6
    infun  
       331 天前
    作为测试,我想说,这种行为 非常之 SB
    但还是经常遇到
    7gugu
        7
    7gugu  
       331 天前
    能跑就行
    Aluhao
        8
    Aluhao  
    OP
       331 天前
    @chendy 请求的数据包,JSON 里加 JSON ,还得正确系列化,少一个 / 都是不行。
    kaedeair
        9
    kaedeair  
       331 天前
    有时候要保持数据结构一致性,不得已的做法
    ospider
        10
    ospider  
       331 天前
    k8s 的 yaml 不久经常有么……
    AoEiuV020CN
        11
    AoEiuV020CN  
       331 天前
    常见,易用,丑,
    hronro
        12
    hronro  
       331 天前
    说正常的大概是自己也经常写这种屎代码?
    jeesk
        13
    jeesk  
       331 天前
    没办法的事, 谁想这么搞?
    bubble21
        14
    bubble21  
       331 天前
    抖音就是这么干的
    lessMonologue
        15
    lessMonologue  
       331 天前
    @hronro 那优雅的写法是什么呢?
    muyiluop
        16
    muyiluop  
       331 天前
    我跟你看法一样,跟上面以及下面的人看法也相同
    YepTen
        17
    YepTen  
       331 天前   ❤️ 1
    有时需要进行签名,签名与验签需要保持 key 的顺序不变。而某些 JSON 解析框架(对,就是你 Fastjson )会自动排序你的 key ,导致不一致。整成个字符串好一些,也就这个场景下有点好处。
    tedzhou1221
        18
    tedzhou1221  
       331 天前   ❤️ 5
    有些功能就这样,它只负责第一层数据,至于 data 里的是什么,它不管,它会把 data 的内容向下传递。
    missdeer
        19
    missdeer  
       331 天前 via Android
    大胆一点,就是菜。不一定是写这个的人菜,也可能是他依赖的某个接口的作者菜。
    crysislinux
        20
    crysislinux  
       331 天前
    > 有些功能就这样,它只负责第一层数据,至于 data 里的是什么,它不管,它会把 data 的内容向下传递。

    一般这种用法就是上面说的这种情况。
    Rache1
        21
    Rache1  
       331 天前   ❤️ 4
    在一些需要签名的场景,会需要用到的。

    还有一些场景,假设这个 json 来自上游,有的 JSON 解析器会有全局配置,可能在别的地方给配置了,就可能会把数字字符串变成了数字,小数位为 0 的浮点数转成了整数,等等。

    还有比如 PHP 里面的 json_decode ,大部分人会习惯性的给第二个参数添加一个 true , 以返回一个 PHP 的数组,方便使用,而这种情况就最容易出问题的就是,某个字段的值,如果对方放回的是一个空的对象 {},经过 php 这样一转换,就成了 [] 了,当然这些都是人为因素。

    jowan
        22
    jowan  
       331 天前
    你这还好 只是接收 多解析一层就行了
    我对接的腾讯、快手、巨量、VO 厂的广告投放平台
    TMD 提交数据的时候 JSON 里面有个 WHERE 条件必须是 JSON 字符串
    极其丑恶
    yannxia
        23
    yannxia  
       331 天前
    这里有两种可能
    - data 里面是规定格式的,这就是菜
    - data 里面是多态格式的,类型一直在变,对于强类型的语言处理不好,只能用 String 接(虽然 Jackson 有 Type 字段,但是会要求前端传入),这种就是 workaround 没办法。
    Felldeadbird
        24
    Felldeadbird  
       331 天前
    一般来说是设计和迭代上出问题了。 刚开始一个 json 。后面对接多一个接口的数据,他是 json 的。编码的人图省事没整理原路传递下去。
    bollld607
        25
    bollld607  
       331 天前 via Android
    chimission
        26
    chimission  
       331 天前
    我觉得把出现这种情况不可怕, 可能是历史迭代的问题,但是后面不想着把它改掉继续能用就行我觉得有点不可接受
    preach
        27
    preach  
       331 天前
    历史遗留问题 大概率
    dcsuibian
        28
    dcsuibian  
       331 天前   ❤️ 1
    我干过这事,不过具体场景有差别。
    是因为数据库里面这个实体的存储形式就是 JSON 。至于数据库字段为啥要用 JSON ,因为这个字段里的内容太复杂多变了。同样的,如果建立实体类,实体类本身也会常变。因此后端就不转化直接传给前端了,反正前端是动态语言,内置 JSON.parse 方便。
    尤其是一些显示效果、和后端运行无关的。后端做个大概得验证就好了。
    JohnBull
        29
    JohnBull  
       331 天前
    "我要用 JSON,但就是不愿意用最自然的姿势用 JSON,我气死我自己."

    也碰到过类似场景,为防止瞎眼,我直接要求 string 必须 base64
    zhhqiang
        30
    zhhqiang  
       331 天前
    沟通到位就没问题
    russ44
        31
    russ44  
       331 天前 via Android
    如果是自家的后端可以让他处理一下
    onikage
        32
    onikage  
       331 天前
    外层 validate 字段是干什么的?
    如果是 data 是需要校验的话, 这种挺好, 否则还得为每种业务单独定义个顺序,
    这种可以把 data 里面的业务和外层的 validate 校验解耦合, 不需要定义大量的字段顺序.
    feller
        33
    feller  
       331 天前
    微博就是这样的,b 战也是。
    Aluhao
        34
    Aluhao  
    OP
       331 天前
    @onikage validate 签名验证,这个是去向 API 请求的数据包,不是响应数据,如果是响应数据倒没关系,有需要就解出来,没有需要就抛去。
    mtdhllf
        35
    mtdhllf  
       331 天前
    如果包的 json 它的结构是变化的话,可以理解
    ratazzi
        36
    ratazzi  
       331 天前
    多半是为了签名排序,有些人就是不肯直接对 body 签名放在 header ,要排序然后还要各种拼接,写的不累吗
    mringg
        37
    mringg  
       331 天前
    手工造数据比较麻烦
    edis0n0
        38
    edis0n0  
       331 天前
    又不是不能用
    wolfie
        39
    wolfie  
       331 天前
    @lessMonologue
    第一反应都是那
    {
    key: {
    "inner-key": "value"
    }
    }

    上面喷的都是
    {
    key: "{\"inner-key\": \"value\"}"
    }
    aofall
        40
    aofall  
       331 天前   ❤️ 2
    1.反序列化排序问题
    2.数据字段、内容不固定,没有设计专门的字段存储而是靠 varchar 或者 json 存在数据库( MySQL )中
    3.历史问题

    碰到 2 、3 这种情况倒也不是不能弄,多一步处理( Java ):定个 Vo 处理这个字段,用 Jackson 反序列化把这个字段转 Map 就行。

    2 这种情况在所谓的“低代码”、“动态表单”之类的平台很常见

    至于上面说“菜”的,你就说能不能用吧,前端或者后端总有一个人要多写点代码做这种处理的,不是菜,而是有人想偷懒🤣
    singerll
        41
    singerll  
       331 天前
    很多时候都是历史遗留,至于为什么不改掉,跟一大堆系统对接了,改的成本太大了。
    ptrees
        42
    ptrees  
       331 天前
    我就是这么做的,理由是阿里云 api 的 formdata 格式才支持对每个参数设置校验,用 json 就只能自己后台写校验了,为了统一就这么搞了。
    reallynyn
        43
    reallynyn  
       331 天前
    你看下 tcp 协议和 ip 协议,每个协议都有个包头,把 json 想象成包头就行了。。
    IvanLi127
        44
    IvanLi127  
       331 天前
    要么菜,要么图省事。 我看 OP 提供的 JSON 里有个 validate 字段。这个会不会和那个 JSON 字符串有什么关系?
    我怀疑和拿 JSON 字符串参与签名有关系。不过设计成这样那还是要说声菜。
    wyx119911
        45
    wyx119911  
       331 天前
    我写过这种接口,原有后台框架是 protobuffer 序列化的某种规范。因为前端引入一个第三方组件,但组件所需的协议规范与原有框架不一致,返回再包 JSON 影响面比较小。
    chocotan
        46
    chocotan  
       331 天前
    很正常,比如大字段,后端就是 String 类型
    nmap
        47
    nmap  
       331 天前
    看得密恐症犯了
    yyf1234
        48
    yyf1234  
       331 天前 via iPhone
    没对接银行支付类的业务吧?大多都这样,这个字段一般是业务参数,外面的是公共参数
    ruoxie
        49
    ruoxie  
       331 天前
    界面可视化布局都是这么玩的
    shiweiliang
        50
    shiweiliang  
       331 天前   ❤️ 3
    ![]( )
    renmu
        51
    renmu  
       331 天前 via Android
    数据库直接把 json 存成 string 了,然后就变成这样了,挺正常的
    burby
        52
    burby  
       331 天前 via iPhone   ❤️ 1
    感觉还挺正常的,外层服务只是做个透传 就把数据带回来了。有时候为了省一次 API ,有些地方是根本解析不了,背后可能是复杂的架构和补丁造成的。丑陋的接口可能只是这里面最不重要的一点点尴尬
    zzj0311
        53
    zzj0311  
       331 天前
    随便找俩 app 抓包看看 都是这种鬼东西
    April5
        54
    April5  
       331 天前
    找设计接口的人了解这样设计的历史背景 X
    v2ex 发帖,怎么看待请求参数 JSON 数据包里再包 JSON 数据 √
    ZRS
        55
    ZRS  
       330 天前 via iPhone
    傻逼行为 但我刚遇到一个
    lmw2616
        56
    lmw2616  
       330 天前
    说不正常的大概是没做过三年级以上的项目吧[狗头]
    xz410236056
        57
    xz410236056  
       330 天前
    data 里面是个字符串? 那确实傻逼。
    @lessMonologue #15 正常里面是 JSON object 啊
    lmmlwen
        58
    lmmlwen  
       330 天前   ❤️ 1
    没问题啊,我不知道各位是天天沉浸在博客还是自我臆想中,这种做法不管是大厂还是初创都很常见
    lakehylia
        59
    lakehylia  
       330 天前
    base64 一下会好看一点
    jorneyr
        60
    jorneyr  
       330 天前
    看情况,有的时候使用是非常方便的。
    例如配置内容保存到数据库,不会去进行搜索,所以会把对象序列化为 JSON 字符串保存到数据库。由于后端返回前端的响应体格式是统一的: { code, message, data },配置内存肯定是放在 data 字段,所以是一个 data 是一个 JSON 字符串很正常,否则后端需要把 JSON 字符串解析成对象,然后放到 data 下,没多大必要。
    jjwjiang
        61
    jjwjiang  
       330 天前
    同样的接口返回不同的数据结构就得这么做,这样的设计不是很常见吗
    Aluhao
        62
    Aluhao  
    OP
       330 天前
    @jjwjiang 这是请求接口数据,而不是返回响应的数据。
    Torpedo
        63
    Torpedo  
       330 天前
    @YepTen 签名不应该大家约定一个 key 的排序方式吗?而且 json 的规范里,也没有保证对象 key 的顺序
    yurenchen
        64
    yurenchen  
       329 天前 via Android
    这可能是一种分层设计
    外面是传输层
    里面是应用层, 应用层有 json 错误也不影响 传输层的工作, 传输层只管 有效送达 忠于原文 (也算是种封装隐藏内部细节
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1112 人在线   最高记录 5930   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 18:23 · PVG 02:23 · LAX 11:23 · JFK 14:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.