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

了解下现在接口返回都是什么形式, 要不要提示文本?

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

    http, json. 以登录接口为例, 两种方案:

    1. 返回{"code":0} 代表成功, {"code":1} 代表用户名密码不匹配. 前端页面自己根据 code 显示不同提示文案.
    2. 返回{"code":0,"msg":"登录成功"}, {"code":1, "msg":"用户名密码不匹配"}, 页面上直接显示 msg 属性的文本. 我个人认为第二种非常啰嗦, 一个 code 足以说明问题, 但是好像不少人都习惯第二种.
    77 条回复    2021-07-29 08:45:26 +08:00
    Bazingal
        1
    Bazingal   124 天前
    第二种,前端不用写一堆枚举
    coolcoffee
        2
    coolcoffee   124 天前
    同样是第二种,你封装好以后,自动将 code 对应的提示语带出来就好了。 这样能方便调试以及前端提示,同时也能根据特殊 code 单独处理逻辑。

    不然后端自己 postman 调试的时候,看到 code 还要有个查询或者去读记忆过程。
    nekoneko
        3
    nekoneko   124 天前   ❤️ 1
    我现在要根据用户的预言返回 中文,拉丁文,英语,日语,繁体中文,阿拉伯语,法语,德语,韩文,俄语,西班牙语,葡萄牙语,印地语.你是要前端来搞嘛?今天我又要加一种语言呢?
    misaka19000
        4
    misaka19000   124 天前
    第二种,方便排查问题
    sunjiayao
        5
    sunjiayao   124 天前
    接口响应状态还是第二种好。
    一个 code 对应不同 msg 时,前端只需要阻断当前流程并 toast 提示即可。
    kop1989
        6
    kop1989   124 天前
    如果是第一种的话,你怎么保证前端的 code 与后端的 code 语义一致呢?
    adnoh
        7
    adnoh   124 天前 via Android
    我现在接口都用这种形式的了{"ok":true,"msg":"登录成功","data":{}}
    aogu555
        8
    aogu555   124 天前
    第二种,如果第一种的话如果需要增加 code 类型,那么需要通知前端去修改 msg 映射,而且也要单独维护一份接口文档,但是第二种后端自己改就行了,减少不必要的沟通成本。
    onikage
        9
    onikage   124 天前
    @nekoneko 增加一种语言难道前端不用改么? 第一种的话在增加语言时只需要前端发布新版本就好, 第二种新增语言前后端都得有工作量.
    onikage
        10
    onikage   124 天前
    @Bazingal 你是前端吗? 这部分工作量无论前后端都得做. 我作为后端来说, 这部分想图省事扔到前端做.
    onikage
        11
    onikage   124 天前
    @sunjiayao 一个 code 怎么对应不同 msg?
    onikage
        12
    onikage   124 天前
    @aogu555 这个场景倒是很有道理.
    anzu
        13
    anzu   124 天前
    当然是第一种,方便以后做 i18n,不用再通知后端用户切换了语言。至于前后端 code 一致性,如果懒得写文档,后端可以另写一个内部用的接口枚举所有 code 映射,前端请求一下即可。
    sunjiayao
        14
    sunjiayao   124 天前
    @onikage 比如说定义 code 1 为错误 code 。msg 有可能是 用户名密码错误 验证码错误 验证码发送过于频繁 等等
    h1104350235
        15
    h1104350235   124 天前
    第二种好
    onikage
        16
    onikage   124 天前
    @anzu 对, 我也是这么想的. 但是目前公司内支持第二种的人比较多.
    onikage
        17
    onikage   124 天前
    @h1104350235 好在哪里?
    onikage
        18
    onikage   124 天前
    @sunjiayao 这样其实可以通过定义多个错误代码解决.
    onikage
        19
    onikage   124 天前
    @kop1989 接口文档啊.
    sunjiayao
        20
    sunjiayao   124 天前   ❤️ 1
    @onikage 其实一般来说,不需要执行特殊流程的异常返回是不需要单独定义 code 的。我的习惯是这样
    falcon05
        21
    falcon05   124 天前 via iPhone   ❤️ 1
    第二种,方便自己调试。不写文档
    SoloCompany
        22
    SoloCompany   124 天前
    i18n 已死请烧纸
    Kilerd
        23
    Kilerd   124 天前   ❤️ 7
    第一种,但是会遵循第二种加一个 msg 不过是 enum 格式的
    例如:
    登录成功: {"code":0,"msg":"LOGIN_SUCCESS"}
    密码不对: {"code":1, "msg":"INVALID_PASSWORD"}

    这样前端可以用 msg 里面的 key 做 i18n

    别说 i18n 没用,问就是你做的项目不够国际化。
    gamexg
        24
    gamexg   123 天前
    app 等本地应用,
    gamexg
        25
    gamexg   123 天前
    @gamexg #24

    app 等本地应用,不建议第一种.
    app 发布时不可能预期到所有错误提示,后期绝对后出现变更.
    第一种没有了灵活性.
    wheeler
        26
    wheeler   123 天前 via iPhone
    借楼问下,有了 code 之后 http 响应码是都返回 200 吗?
    Leonard
        27
    Leonard   123 天前
    第二种,灵活一点,后台可以随意新增新的提示语
    whusnoopy
        28
    whusnoopy   123 天前   ❤️ 1
    参与讨论

    先回答 #26 的问题:有了 code 以后 HTTP 响应码都返回 200 。原因一是因为 HTTP 码表示的是网络层的成功与否,而接口的很多错误并不是网络层的,二是即使是网络层的错误,比如 403 Forbidden,如果直接在 HTTP 响应码返回,可能会被更上层的框架拦截处理,压根到不了应用里来处理

    另外回楼主,为什么非得争论哪个好,不能一起用。实践中我这边一般返回的都是 `{"code": 1, "msg": "登录失败:用户不存在", "data": {}} ` 这样的,前端通过 0 和非 0 判断是否成功,对于非 0 的情况,可以根据 code 去自己组织异常处理和用户反馈(可能还用到 data 里的内容),也可以用我们自己框架层逻辑直接显示 msg 并退出调用

    一般最终的处理逻辑和标准都是以后端为准,哪怕后端实现错了那也才是真实情况,所以我写后端会连 code 带 msg 并附上 data 一起返回,前端爱怎么用随便他(虽然大多数时候是另一个我
    yolee599
        29
    yolee599   123 天前
    @wheeler #26 返回 200 可以保证所有应用错误都能收到,应用错误用 http 响应可能被丢弃,到不了应用层。
    otakustay
        30
    otakustay   123 天前
    你能不能保证你的 code 的 msg 永远是一对一的,如果可以就不需要 msg 了让前端做字典就行,做国际化也方便些
    但我从来没见过 code 和 msg 能一对一的时候,最糟糕的兜底错误怎么处理呢?
    masterclock
        31
    masterclock   123 天前
    借楼,第二种,多语言化怎么解决的?前端请求的时候带着语言信息,服务之间传递下去,每个服务各自处理多语言?
    netwjx
        32
    netwjx   123 天前
    1 和 2 的真实差异是?

    我猜的: 每次网络通讯, 1 比 2 快 1ms? 每次 debug, 2 比 1 快一小时?


    不涉及核心的比较(比如用"好" 来形容 )都是耍流氓
    nekoneko
        33
    nekoneko   123 天前
    @adnoh #7 这种返回对 对接 不太友好,跟前端交互足够
    nekoneko
        34
    nekoneko   123 天前
    @onikage #9 前端所有文本都由后端返回,前端只需要做好显示功能
    Hallelu
        35
    Hallelu   123 天前
    第一种的话,能保证一对一,是最好的。但我对接的,还没见过一个 code 就是对应一个 msg 的,例如密码失败,用户已登录,这种情况,用第一种还得再去请求一下。
    aliveyang
        36
    aliveyang   123 天前
    第二种,不要增加沟通成本
    Jooooooooo
        37
    Jooooooooo   123 天前
    当然是第二种

    后端来维护各种文本远比前端要灵活
    lei2j
        38
    lei2j   123 天前
    肯定第二种好,后端解决更好。
    akira
        39
    akira   123 天前
    喜欢第二种,调试起来各种方便
    ccyu220
        40
    ccyu220   123 天前   ❤️ 4
    肯定是第二种啊,前端在 header 中提交语言代码,后端根据语言返回不同的语言提示。
    makun123
        41
    makun123   123 天前
    必须第二种好,使用起来也更灵活些,一个 code 可以对应多个 msg,我还有场景用到,一个 code 对应的 msg 提示中拼接一些业务处理后的提示参数,第二种直接返回了,第一种还得和 FE 特殊约定下
    makun123
        42
    makun123   123 天前
    还有题外问下楼主已经 40+了么
    FallenTy
        43
    FallenTy   123 天前
    第二种后端也能做国际化,功能实现都一样,这种就是少数服从多数了。
    KyrieJoshua
        44
    KyrieJoshua   123 天前
    @onikage 10L
    如果抱着图省事的心态让前端做,以后前端就不理你了。。
    zgray
        45
    zgray   123 天前
    有种场景必须用 2,而不能用 1 。

    当后端有个原来预想外的逻辑要额外增加错误提示,但是发布前端已经来不及(前端可能是 APP,或者是利用 electron 之类的客户端方案),必须后端先修复,这个时候前端如果是用 msg 提示,那么后端是可以立刻修复后发布。而不给 msg 只用 code,前端这时候只能报“内部错误”这样的提示了。
    ily433664
        46
    ily433664   123 天前
    肯定是第二种,就算你想让前端自己控制提示语句,第二种也可以兼容
    queuey
        47
    queuey   123 天前
    第一种很傻,
    code 是通用的,如果按照第一种来的话,付款失败可能有几十种原因,判断 code 给几十个 前端自己处理?
    Hslacker
        48
    Hslacker   123 天前
    第二种,前端不用写一堆枚举
    ytmsdy
        49
    ytmsdy   123 天前
    第二种吧!这样还能悄咪咪的加入一些其他的提示脚本,这样前端就不需要重新发布。
    要不然新增一个提示信息,前端需要修改,后端也需要修改。
    zxCoder
        50
    zxCoder   123 天前
    第二种,只用修改一端
    aguesuka
        51
    aguesuka   123 天前
    当然要, 后者是前者的超集, 第一种方案能实现的第二种都能实现. 第一种情况需要维护一个超级大的枚举, 非常反设计.
    balabalaguguji
        52
    balabalaguguji   123 天前
    刚好有写一个响应参数的教程 https://easydoc.net/posts/response-data-design/
    libook
        53
    libook   123 天前
    看需求。

    如果前端需要对文本进行风控或限制的话,第一种方案比较合适。
    如果希望能快速调整文本的话,第二种比较合适。
    liuhuihao
        54
    liuhuihao   123 天前
    当然是第二种
    常见的场景就是 APP,产品可能要修改一个小小的错误文案,使用第一种的话,就要给所有用户推送更新才行,第二种后端直接修改即可。
    sytnishizuiai
        55
    sytnishizuiai   123 天前
    我一开始想用 1,但是 msg 中文也写了,顺带的,后来慢慢变成 2 了,code 自己写多了烦,还要写文档,前端找,还不如用 2 的方式,我现在 code 也不写多了,除非需要前端去判断的才额外写个 code 。
    onikage
        56
    onikage   123 天前
    @netwjx 作为后端, 我认为的核心就是少一部分工作量以及对应的 bug.
    onikage
        57
    onikage   123 天前
    waytoshine
        58
    waytoshine   123 天前 via iPhone
    你的观点,只能说你目前没做过什么稍微大点的系统的开发
    kekxv
        59
    kekxv   123 天前 via iPhone
    前端:?要不要我把后端接口也做了?🐶
    onikage
        60
    onikage   123 天前
    @waytoshine 什么叫大?
    makun123
        61
    makun123   123 天前
    @onikage 对外提供服务的 api 肯定是要是要一个 code 对应一个 msg
    onikage
        62
    onikage   123 天前
    @makun123 快了
    IvanLi127
        63
    IvanLi127   123 天前 via Android
    非生产环境 具体的错误描述得给。在生产环境中,如果没有其他可选项的话,我选第二种。
    daimubai
        64
    daimubai   123 天前
    肯定第二种,对于可变的东西后端做控制更好,毕竟产品总是需要改文案什么的,而且第二种前端调试起来也方便吧,至于国际化,如楼上所说,可以在请求头中传递 language,不过我想大多人的项目还用不到国际化
    Felldeadbird
        65
    Felldeadbird   123 天前
    第二种。国际化解决方案很多啊。 后端判断,前端判断。两端一起判断。第二种可以直接定位到错误。

    第一种需要准确定制 code 码,后期维护成本高
    queuey
        66
    queuey   123 天前
    @onikage 57 微信这种是提供 API 给到外部的啊,和自己做完全不是一个概念。你要是觉得 1 好那就用 1 呗。只要你们前端没意见
    xujinkai
        67
    xujinkai   123 天前 via Android
    第二种方便调试,前端不一定用但不能没有
    gtanyin
        68
    gtanyin   123 天前
    见过懒的后端,没见过你这么懒的。。
    xianxiaobo
        69
    xianxiaobo   123 天前
    我前后端都自己写,我选择第二种,维护方便啊,要改 code 和 message 只要改后端代码就行了。不然后端代码加个 code,然后前端代码再去加 message?
    whusnoopy
        70
    whusnoopy   123 天前
    @onikage 关于微信的返回码

    1. 人家给了全局返回码又不是不能再多带个 msg 和 data,多带 msg 和 data 并不影响你本来就有 code 返回和 code 全局唯一性,比如 code 是 -1 表示「系统忙,请稍后再试」,那到底是等一秒后重试还是一分钟后重试,这种就可以在 msg 和 data 里体现了

    2. 微信的开放平台也不是必然正确和唯一正确的做法,比如他们家授权过程还要带着 appid 和 secret 明文传这就很诡异 https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html,虽然有用 https,虽然可以设置 IP 白名单,对比下支付宝,都是公私钥签名验证 https://opendocs.alipay.com/support/01rave
    penll
        71
    penll   123 天前
    微信的 code 要看具体情况。msg 是给用户的友好信息,code 是能定位到具体问题,难道你要告诉用户 xxx 参数不能为空这种情况吗?
    EmotionV
        72
    EmotionV   123 天前
    明显第二种啊,要是 pm 说要改个提示,后台直接改下上线就行。app 啥的还要重新打包提交审核,麻烦的很。
    strongcoder
        73
    strongcoder   123 天前
    {
    "status": "200",
    "msg": "OK",
    "isPC": 1,
    "isHome": 1,
    "data": {
    "status": "0",
    "data": "new"
    }
    }
    no1xsyzy
        74
    no1xsyzy   123 天前
    type Response<T, F> = {code: "SUCCESS", data: T} | {code: F};

    例:
    {"code": "SUCCESS", data: {"token": "..."}}
    {"code": "BAD_LOGIN"}
    {"code": "UNKNOWN_ERROR"}
    {"code": "SERVER_DOWN"}

    说了多少次,不要用数字暧昧地表示状态,用 Symbol 去明确。那样后端调试也不需要查询或记忆 code
    成功就是成功不需要 msg,warning 不应当以 toast 形式提供。

    (有时返回 http code 444 以实现某些目的)

    评论,这问题甚至不值得辩论,因为最优选项显而易见:

    #23 差门前一脚,code 的存在毫无意义,enum msg 不就足以提供所有信息了吗?

    #25 所说的,应当采用单独的接口传递以实现关注点分离。

    #34 那为什么要返回 json,直接 html 返回整个网页解决所有问题。 —— 我确实有这么干的。

    #71 接口返回信息不应当用于定位问题,定位问题应当用后端 log,否则可能泄漏代码形态和逻辑。
    netwjx
        75
    netwjx   123 天前
    @onikage 研发过程成本 和 运行时成本 比起来

    几乎可以忽略, 否则软件行业不会这么发达

    所以决策判断应以后者为主, 降低运行成本, 减少运行风险
    onikage
        76
    onikage   122 天前
    @gtanyin 实际早年还写 jquery 那会因为前后端都是一个人, 所以就是这么搞的. 也没感觉增加多少工作量.
    gtanyin
        77
    gtanyin   121 天前
    @onikage 好的,学习了~
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2210 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 05:13 · PVG 13:13 · LAX 21:13 · JFK 00:13
    ♥ Do have faith in what you're doing.