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

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

  •  1
     
  •   Aluhao · 2022-10-27 10:32:03 +08:00 · 6778 次点击
    这是一个创建于 759 天前的主题,其中的信息可能已经有所发展或是发生改变。
    请求数据结构如下:

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

    一般这种用法就是上面说的这种情况。
    Rache1
        21
    Rache1  
       2022-10-27 11:28:53 +08:00   ❤️ 4
    在一些需要签名的场景,会需要用到的。

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

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

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

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

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

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

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

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