虽然萝卜白菜各有所爱,我个人坚持认为对于REST接口,就应该用HTTP层面的status来表达操作是否成功。
HTTP status直接500,相当于回答:“请求出错了。”
HTTP status层面是说是200,在payload里写500,等于服务器这样的回答:“请求成功了,但是其实是出错了。”
现在,调用那一端不得不要理解一下这个非常晦涩的话语,除了明确用500 status表示出错,在接到“成功”请求的时候,依然要看一看它的内容是否出错,多一个判断,就多一份麻烦,就多一份出bug的机会。
更要命的是,网络通讯不只是一个客户端一个服务器的事情,中间会有很多层节点,如果其中某一个Proxy对status 200的请求理解非常正统,做了cache或者什么处理的话,那就……惨了。
所以,最好还是老老实实用HTTP的500 status。
next.js也犯过一样的错误,把4XX、5XX的错误当200返回,导致社区怨声载道,最后next.js不得不改过来。
最后多说一句,题主给的错误截屏里,错误原因是“最高教育经历只能存在一个”,这看起来是客户端调用给错了参数或者连续重复一个操作导致的问题,简单说,这是客户端过错,不是服务器出错,status应该是4XX,而不是5XX。
我观点一直是这样,
要么,严守REST,HTTP Request/Response就是API,语义就是操作,那么Status Code就是反映你的API返回结果的状态的东西。那么绝不应该在Payload里面写实际的状态。
要么,严守普通的上下层包装逻辑,HTTP就是传输层,HTTP的200表示传输没错,500表示传输过程中断了。
但,如果是后者的话……你的Payload里面用HTTP Status Code是个什么玩法?这些状态都是特定于HTTP的啊,用来表示Business Logic的状态真的没问题么……还是说你的Business Logic就是另一层HTTP……………………这个太诡异了。
当然不够合理,我个人是非常反对将HTTP协议仅作为传输协议来用的,HTTP作为传输协议显然并不是最佳选择。
抛弃HTTP协议语义意味着什么?意味着整个互联网上的HTTP设备资源都无法正常利用。譬如说GET,如果严格遵循语义,对于同一URL永远返回相同结果,那么CDN的缓存就能解决大量问题,极大的优化响应时间和传输成本,降低服务器的压力。而如果该URL或者服务器处理中出现了错误,HTTP错误码也能被所有的HTTP设备识别。自动对错误的结果不进行缓存。
互联网上这么多现成的支持HTTP的设备,有的可以缓存分发,有的可以负载均衡(遇到503自动冷却),有的可以监控统计(记录错误请求,分析攻击行为)。就这样因为一些不学无术连HTTP协议都搞不懂的后端程序员浪费了……