V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
kkshell
V2EX  ›  问与答

接口返回格式的问题,很苦恼

  •  
  •   kkshell · 2019-04-15 21:36:17 +08:00 · 3402 次点击
    这是一个创建于 1809 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我是一名渣渣 PHPer,公司做项目我负责开发 API 供 APP 端使用,可是 Android 端出现了如下的要求。 以下数据都是通过 json_encode 后的数据 比如返回数据列表如下(有数据的情况下) { "status": 200, "msg": "获取成功", "data": { "user_id": 1906, "maintenance_id": 2825 } }

    无数据的情况返回如下 { "status": 301, "msg": "获取失败", "data": [] } }

    然后 Android 端说获取失败也好什么也好,data 那里都要返回对象给他才行,不能有数据时是对象,无数据时又变成数组。可能是我菜,但我认为这是正确的返回。IOS 端也认为没问题,然后 Android 说他用的框架没有办法像我这样返回进行接收,说框架作者讲了只能这样接收,还有说他以前都是这样,同学都是这样接收的。

    无奈之下进度问题上网百度谷歌之后,使用 JSON_FORCE_OBJECT 进行操作 $data = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_FORCE_OBJECT);

    虽然 data 为空的时候是能解决问题,但是如果 data 二维数组的时候,就会变成如下格式,Android 和 IOS 都不好接受 { "status": 200, "msg": "获取成功", "data": { "0": { "suites_id": 379, "suites_number": "102" }, "1": { "suites_id": 431, "suites_number": "101" } } }

    因此非常苦恼,导致只能在空的时候换成以下这种格式返回 { "status": 301, "msg": "获取失败", "data": { "user_id": 0, "maintenance_id": 0 } }

    我之前都没遇到过需要这样返回的,我认为我返回的是 JSON 的默认格式,没有问题,大伙们帮我看看,也许是我能力不足,没有遇到过这样的问题,我现在不知道怎么修改才好,还是说我没有错怎么说服他呢?

    第 1 条附言  ·  2019-04-15 22:35:44 +08:00
    问了用的是这里的框架,不知道有没有大佬可以给个解决方案? https://github.com/zhou-you/RxEasyHttp/issues/53
    43 条回复    2019-04-17 10:36:23 +08:00
    kkshell
        1
    kkshell  
    OP
       2019-04-15 21:36:52 +08:00
    这代码的格式有点问题阿,辛苦各位帮我看看咯
    kkshell
        2
    kkshell  
    OP
       2019-04-15 21:42:47 +08:00
    求指点迷津
    Sanko
        3
    Sanko  
       2019-04-15 21:43:39 +08:00 via Android
    android 菜
    kkshell
        4
    kkshell  
    OP
       2019-04-15 21:48:32 +08:00
    @Sanko 那怎么说服他呢
    heIIokitty
        5
    heIIokitty  
       2019-04-15 21:48:45 +08:00 via Android
    根据 status 判断不就 ok 了吗
    kkshell
        6
    kkshell  
    OP
       2019-04-15 21:49:53 +08:00
    @heIIokitty 他说接收格式要统一。。
    heIIokitty
        7
    heIIokitty  
       2019-04-15 21:52:38 +08:00 via Android
    @kkshell 我也是 Android 开发,我就没听过框架不能改,代码是死的,人是活的,他这是杠
    alakey1989
        8
    alakey1989  
       2019-04-15 21:53:02 +08:00
    data 做下判断,如果为空数组,就转换成 object。如$data = (object)[];
    Nasei
        9
    Nasei  
       2019-04-15 21:53:15 +08:00
    话说为啥没数据的时候还要带个 [] , 直接没有这个字段不行么
    pubby
        10
    pubby  
       2019-04-15 21:54:47 +08:00 via Android
    最简单的做法是失败的时候不要包含 data 项
    Kylinsun
        11
    Kylinsun  
       2019-04-15 21:55:04 +08:00 via iPhone
    kkshell
        12
    kkshell  
    OP
       2019-04-15 21:55:15 +08:00
    @alakey1989 如果是二维数组他就要[]
    kkshell
        13
    kkshell  
    OP
       2019-04-15 21:57:04 +08:00
    @Kylinsun 你这个貌似可以,谢谢
    kkshell
        14
    kkshell  
    OP
       2019-04-15 21:57:37 +08:00
    @pubby 不返回他更不行 - -
    kkshell
        15
    kkshell  
    OP
       2019-04-15 21:58:13 +08:00
    @Nasei 但是就算是不反悔 data 项他也接不了啊
    Nasei
        16
    Nasei  
       2019-04-15 22:03:46 +08:00
    @kkshell 可以的吧, 虽然我不写 java , 但我猜他是把 json 反序列成一个类了, 那个类的字段类型是确定的, 默认情况下碰到数组反序列化失败了? 但是没有字段一般他会拿到 null
    ODD10
        17
    ODD10  
       2019-04-15 22:04:11 +08:00 via iPhone
    按我个人认为,保持一致性挺好的。不是扛。
    kkshell
        18
    kkshell  
    OP
       2019-04-15 22:04:44 +08:00
    @ODD10 好吧
    kkshell
        19
    kkshell  
    OP
       2019-04-15 22:09:38 +08:00
    @ODD10 但是无数据的时候,还要返回{ "status": 301, "msg": "获取失败", "data": { "user_id": 0, "maintenance_id": 0 } }不觉得是多此一举吗
    humpy
        20
    humpy  
       2019-04-15 22:09:53 +08:00 via Android   ❤️ 1
    这是 php 的 array 混合了 list 和 map 的锅。

    java 也不是不能处理,先按对象解析,解析不了再按列表解析就行了。

    不过最好还是 php 改,json_encode($data ?: new stdClass) 就行了。其实我建议少用数组,这玩意害人害己,定义一个数据类也花不了多少时间
    kyuuseiryuu
        21
    kyuuseiryuu  
       2019-04-15 22:11:45 +08:00
    在所有语言之中,只有 PHP 的数组定义的最奇葩。明明是 K-V 结构偏偏要说是 关联“数组”,硬生生叫成“数组”。保持结构统一,你应该返回 data:null 给他。
    laoyur
        22
    laoyur  
       2019-04-15 22:15:51 +08:00 via Android   ❤️ 2
    就事论事,有数据时返回对象,没数据时返回空数组,我觉得就是设计失败,换我做 Android 我也发飙,不是 Android 端能不能解决的问题,也别跟我说是 php 的锅,在我看来就是设计的锅,对,就是这么严格
    ODD10
        23
    ODD10  
       2019-04-15 22:18:21 +08:00 via iPhone
    @kkshell #19 这我就说不准了,我个人是不需要,空对象即可
    misaka19000
        24
    misaka19000  
       2019-04-15 22:18:44 +08:00
    可以选择 {} 或者 null,但是 [] 绝对不是一个好的设计
    maninfog
        25
    maninfog  
       2019-04-15 22:22:32 +08:00 via iPhone
    作为 Android 开发感觉是你的问题。一般 data 用范型限定类型都是数据对应的实体类,而你返回一个数组直接导致 json 解析报错。我觉得正确的做法是 9 楼说的,301 的时候返回 null 就行了。
    kkshell
        26
    kkshell  
    OP
       2019-04-15 22:34:15 +08:00
    @misaka19000 确实
    @maninfog 他说返回 null 也不行,框架问题 https://github.com/zhou-you/RxEasyHttp/issues/53
    @kyuuseiryuu 他说返回 null 也不行,框架问题 https://github.com/zhou-you/RxEasyHttp/issues/53
    zqx
        27
    zqx  
       2019-04-15 22:38:48 +08:00 via Android
    我认为接口在任何状态下都应该返回相同的字段和类型,值可以为空。如果接口的返回值字段和类型不唯一,那么前端(客户端)就要写更多的垃圾代码弥补不稳定的接口缺陷
    newmind
        28
    newmind  
       2019-04-15 22:39:49 +08:00
    失败时可以选择不要 data
    kyuuseiryuu
        29
    kyuuseiryuu  
       2019-04-15 22:43:24 +08:00
    @kkshell #26 空指针异常本来就应该在代码里显式捕获的,如果是框架没抛出来自己崩了,那是框架问题,如果框架抛出来了,自己没有去 catch 或者判断,那就是你们安卓菜得扣烂🦶
    huangdayu
        30
    huangdayu  
       2019-04-15 22:47:03 +08:00 via Android
    返回值的类型保持一致是最好的,无论是对象还是集合,不过首选集合啊,返回一个空的 list 没毛病,json 解析也没毛病。不一致的话,反序列解析就报异常了
    maninfog
        31
    maninfog  
       2019-04-15 22:47:10 +08:00 via iPhone
    @kkshell 老哥 我说的是 data 字段为 null 而不是 response 为 null 啊
    miao666
        32
    miao666  
       2019-04-15 22:49:57 +08:00 via iPhone
    哈哈,安卓确实烦。
    我以前的做法是创建一个全局函数,名为 object 返回一个空对象。
    如果你习惯用 array()结构创建数组,那这种写法应该是狠自然的😂
    现在的的框架 curd 返回值可选对象和数组,你选择下就能避免。
    billlee
        33
    billlee  
       2019-04-15 23:03:06 +08:00
    一个字段有时是 object, 有时是 array 确实不对,但 java 处理不了 null 和缺失字段也是菜。
    kkshell
        34
    kkshell  
    OP
       2019-04-16 10:27:36 +08:00
    @zqx 如果空或者报错时也要显示对应的字段为空的参数,那会出现{ "status": 301, "msg": "获取失败", "data": { "user_id": 0, "maintenance_id": 0 } } 那如果我 data 里是一维数组并且的字段多的话岂不是一堆空字段?这样好吗?我觉得返回空最好了,我这个格式就是通常的返回格式。

    @kyuuseiryuu 这个处理我到时候再问问他,谢谢

    @maninfog 就是 data 字段为 null 阿
    @miao666 老哥,我是 PHP,现在也没其他办法,只能把字段写空,他已经用了框架写完页面了,再改时间不太够
    kiddult
        35
    kiddult  
       2019-04-16 10:54:21 +08:00
    碰上这种事情,怼不回去就放弃,按 android 的来

    乱用不靠谱框架就可以看出 android 那边的水平,没法提高那边就想办法将就,不然项目后面都走不下去
    Mystery0
        36
    Mystery0  
       2019-04-16 11:55:40 +08:00 via Android
    我自己做 Android 开发或者写后端接口的时候,返回的数据格式是成功返回带 data 的 json,失败不带 data (只有 msg 和 code ),客户端用 gson 解析,然后定义了 base response (只有 msg 和 code ),不同的接口返回数据定义 JavaBean 的时候继承 base response,添加 data 字段同时确定类型,希望有所帮助。看了描述,总觉得 Android 开发死守一个框架不是很好,用的框架没办法的时候换一个不就行了....
    Mystery0
        37
    Mystery0  
       2019-04-16 11:57:18 +08:00 via Android
    说白了就是 Android 开发技术不行,就是想少做一些事情而已
    maninfog
        38
    maninfog  
       2019-04-16 12:51:54 +08:00 via iPhone
    @kkshell data 只是一个属性为 null 怎么会解析不了呢,惊了
    caotian
        39
    caotian  
       2019-04-16 13:04:11 +08:00
    我也遇到过这个问题, 返回 new StdClass 就变成{}了
    kkshell
        40
    kkshell  
    OP
       2019-04-16 19:07:52 +08:00
    @caotian json_encode($data ?: new stdClass)是这样写吗?我这样写了返回一点没变= =
    s609926202
        41
    s609926202  
       2019-04-16 19:30:41 +08:00
    kkshell
        42
    kkshell  
    OP
       2019-04-17 10:35:28 +08:00
    @caotian 不行,如果是下面这种的话,空的时候就要返回"data":[]
    {
    "status": 200,
    "msg": "成功",
    "data": [
    {
    "id": 163,
    "registration_id": null,
    "sex": "女"
    },
    {
    "id": 163,
    "registration_id": null,
    "sex": "女",

    "integral": 0,
    "sign_num": 0
    }
    ]
    }
    kkshell
        43
    kkshell  
    OP
       2019-04-17 10:36:23 +08:00
    @s609926202 麻烦看上一楼
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   926 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:54 · PVG 04:54 · LAX 13:54 · JFK 16:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.