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

RESTFul 后端返回什么 HTTP 状态码比较规范

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

    请问 RESTFul 后端响应的 HTTP 状态码应该是什么比较规范?

    我们现在是全部返回200,只有后台挂了,或者是代理错误前端才会受到错误码

    比如登录的账号密码错了,api 会返回 status=200 ,并在 body 部分返回错误码和 message 。 或者查找用户,用户不存在,也会返回 200 ,并在 body 部分返回错误信息。

    我们决定这么做的原因是 能够通过状态码区分是 CDN/代理的错误,还是后台挂了。只要状态码是 200 ,就说明后台没挂


    我参考了几个网站,发现他们的 api 如果操作错误,会响应具有语义的状态码。比如查找不存在,会返回 404 ;登录密码错误,会返回 5XX 。


    请问这种实现规范么?有没有什么可以参考的?

    请大家指教,谢谢!

    33 条回复    2024-01-14 17:47:33 +08:00
    XCFOX
        1
    XCFOX  
       105 天前
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status
    一般 4XX 是服务报错,5XX 是运维(CDN/代理)出了问题
    oneisall8955
        2
    oneisall8955  
       105 天前 via Android
    月经贴
    IvanLi127
        3
    IvanLi127  
       105 天前 via Android
    不规范,完全不规范。5xx 那么好几个,足够覆盖服务器、反向代理、CDN 挂了的情况
    yolee599
        4
    yolee599  
       105 天前 via Android
    http 返回的是 http 状态码,body 返回的是应用状态码,这样分开通用性和易读性更强一点,开发只需要专注应用状态码就可以了
    batchfy
        5
    batchfy  
    OP
       105 天前
    @yolee599 所以说这样统一返回 200 没问题?只要 http 请求发送/接收正常就是 200 ?
    Hurriance
        6
    Hurriance  
       105 天前
    @batchfy 接触的项目基本也是单独放一个应用的状态码,感觉也没啥问题。一方面是区分 http 和应用,另一面有些应用需要有自定义状态码,类似{"code":"100012", "message":"xxxx"},来响应业务本身的错误而已,程序本身其实是没问题的
    insubtemp
        7
    insubtemp  
       105 天前
    我们以前是请求成功统一返回 200 ,body 里放业务状态码,但是后期发现还是不太好,比如说有一些库或者框架抛出的错误难以全部捕获,这时库或框架会直接抛出 500 之类的给客户端,body 是没有经过包装的
    所以我们现在都是合并请求状态码和业务状态码,比如权限问题 401 ,业务失败 4xx ,前端只要发现不是 200 就走错误处理逻辑了,不需要再处理 body ,处理起来比较清晰
    mywowo
        8
    mywowo  
       105 天前
    中间件一般处理不了业务状态码,用 HTTP 状态码好一点。
    iseki
        9
    iseki  
       105 天前
    用户/业务触发错误 4XX ,服务端故障 5XX ,RESTful 就请遵守 HTTP 。不要搞 POST 200 然后里面塞个 30008 之类的事,喜欢这样干的去用 RPC over HTTP ,比如 JSONRPC 2.0 / gRPC
    iseki
        10
    iseki  
       105 天前
    出错时可以遵守 RFC 7807 Problem Details for HTTP APIs ,不喜欢用 URL 也可以自己塞一个供前端判定的枚举值
    param
        11
    param  
       105 天前 via Android
    我觉得可以只留两个,200 和 400 。
    成功统一 200 ,不成功统一 400 。
    400 返回错误码和错误信息,200 没有错误码和错误信息。
    yooomu
        12
    yooomu  
       105 天前
    不管接口风格够不够 restful ,我一般用 200 400 (业务上错误,同时会返回业务错误码和错误信息) 401 403 500 (服务器未知错误),这些基本够用了
    Bingchunmoli
        13
    Bingchunmoli  
       105 天前 via Android
    国内一般是没权限 401 参数错误 400 网络异常 500 其他都是 200 然后 bodycode 做业务 code 国外有一些是规范 httpcode 的
    nikenidage1
        14
    nikenidage1  
       105 天前
    https://datatracker.ietf.org/doc/html/rfc7807

    rfc 7807 是对状态码的一个补充,解决具体错误信息的问题
    lcbp
        15
    lcbp  
       105 天前
    统一 200 ,code 区分业务状态,也能携带载荷。
    Beats
        16
    Beats  
       105 天前
    业务相关的统一 200 ,非业务相关的才是别的
    Beats
        17
    Beats  
       105 天前
    @insubtemp 为啥难以捕获?换个程序员吧
    iseki
        18
    iseki  
       105 天前
    成功/失败作为鉴别子,如果出现在带内(响应体),将意味着响应体的形式受到限制,起码响应体得固定是个 JSON 了。而 HTTP 一般用法中并不鼓励这种行为,除非你仅以 HTTP 承载传输,在 HTTP 之上运行其它协议,这样也就不是 RESTful 了。代价是失去 HTTP 提供的特化功能。
    失败信息一般是相对固定的报告,将具体表述,比如错误码、错误消息等写于带内并无不可。
    lovedebug
        19
    lovedebug  
       105 天前   ❤️ 2
    具体 response 结构设置参看 https://github.com/Azure/azure-rest-api-specs
    另外返回的代码,参看 https://learn.microsoft.com/en-us/rest/api/storageservices/common-rest-api-error-codes
    目前开发使用发现,微软的这一套 error codes 和 response 结构可用性较高,值得参考和模仿
    lovedebug
        20
    lovedebug  
       105 天前
    PS:另一个值得参考的 https://github.com/microsoft/api-guidelines
    gudutianya
        21
    gudutianya  
       104 天前
    tyrantZhao
        22
    tyrantZhao  
       104 天前
    统一返回 200 ,内部嵌入业务错误码。
    lizhengbo
        23
    lizhengbo  
       104 天前
    200 到 299 之间的状态码表示成功。300 到 399 之间的代码表示资源已经被移走。400 到 499 之间的代码表示客户端的请求出错。500 到 599 之间的代码表示服务器出错.

    100 ~ 199 100 ~ 101 信息提示
    200 ~ 299 200 ~ 206 成功
    300 ~ 399 300 ~ 305 重定向
    400 ~ 499 400 ~ 415 客户端错误
    500 ~ 599 500 ~ 505 服务器错误
    ychost
        24
    ychost  
       104 天前
    统一 200 最好,业务里面的 code 可以用英文,这样更好理解为什么错了,不然还要查表
    wu67
        25
    wu67  
       104 天前
    老话题了, 状态码统一 200, 业务码你自己定...两个可以不是同一种东西
    tonyaiken
        26
    tonyaiken  
       104 天前 via iPhone
    @XCFOX 这不是写了 5xx 是服务端错误吗
    flmn
        27
    flmn  
       104 天前
    现在最新的建议都是返回能反应业务结果的状态码。

    对于什么结果该返回什么样的状态码,没有什么统一的标准,但是有一些约定俗成。

    对于出错时,返回的 Body ,是有一个 RFC 的: https://www.jitao.tech/posts/problem-details-for-http-apis
    wolfie
        28
    wolfie  
       104 天前
    上家公司 服务端报错返回 600 ,搞得一些组件获取 status_enum 会报错。
    zsh2517
        29
    zsh2517  
       104 天前 via Android
    月经问题(划掉)
    目前习惯是业务逻辑错误 200+自定义状态码,后端代码问题 500 ,其他问题 http 状态码。
    详细来说
    “后端程序”自身的、可预期的异常(通常是正常或者异常的业务逻辑)返回 200 + json 形式自定义错误码和报错信息。很多时候算不上错误,比如用户不存在用户密码错误用户权限不够等等,可能只是抛个异常省事而已。
    “后端程序”自身的、不可预期的异常(如代码 bug 数据库连接挂了 空指针异常等等),走后端框架自身的异常处理,一般是 500 + 打日志事后回顾。
    “后端程序”之外的问题按照原有的 HTTP 状态码返回。比如 cdn 故障,反代故障等等
    ---
    特殊的,比如重定向,文件上传下载,以及部分情况下鉴权之类等等,也会直接用标准状态码,而不是自己写一套。这里只说常见的业务接口。
    ---
    我自己的知乎原文(比较长):
    https://www.zhihu.com/question/513865370/answer/3266494037
    xuanbg
        30
    xuanbg  
       104 天前
    应用错误代码无论是封装在消息体中还是使用 http stats code 都没有问题。

    无论 http stats code 如何跳脚说返回 200 是不合规范的设计,但显然分装在消息体中更普遍也更合理。让协议的归协议,应用的归应用,明确的分层更有利于业务解耦。
    TheWalkingDead
        31
    TheWalkingDead  
       104 天前
    @param 你这个是最荒谬的...
    param
        32
    param  
       104 天前 via Android
    @TheWalkingDead 为什么呢? http 状态码不需要这么多吧,业务错误都是 body 里表示
    TheWalkingDead
        33
    TheWalkingDead  
       103 天前
    @param 你去看看 4xx 代表什么错误吧。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2906 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 09:01 · PVG 17:01 · LAX 02:01 · JFK 05:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.