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

还能不能好好的写 API 了

  •  
  •   jianghu521 ·
    itjhDev · 2016-11-17 17:24:03 +08:00 · 14680 次点击
    这是一个创建于 2936 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我是写 API 的

    写的好好的 REST API. 领导说要重构, 让所有的 HTTP Status 都返回 200. 这不是尴尬吗?

    哎, 找了一堆国内的 API 作对比, 然后我扔给他 github 的 API 看. 但是没有起作用.

    这可如何是好啊!!!

    125 条回复    2019-01-24 11:12:06 +08:00
    1  2  
    tomczhen
        1
    tomczhen  
       2016-11-17 17:32:29 +08:00   ❤️ 1
    要么忍,要么滚。
    Tuisku
        2
    Tuisku  
       2016-11-17 17:32:38 +08:00
    领导说什么你就干什么 不爽就离职
    ↑ 最简单的解决方案 ↑如果你不想听领导的
    xxxyyy
        3
    xxxyyy  
       2016-11-17 17:33:22 +08:00 via Android
    重构?使用 API 的同意了吗?
    huijiewei
        4
    huijiewei  
       2016-11-17 17:33:55 +08:00
    这个不是很简单吗?把 response 再包装一下就可以了
    cxbig
        5
    cxbig  
       2016-11-17 17:34:16 +08:00   ❤️ 3
    外行指导内行的又一案例?
    你有没有问清楚目的?
    如果是对接的那一方限制了 response 的方式而又不能即时改进呢?

    我有见过很多 AJAX 统一用 success 接收 data ,从传回的包里拿 status 做进一步处理的。而不是严格按照 Restful API 的规则来。

    标准是一回事,你可以努力推动。但是实际情况复杂,可能需要一些妥协。
    tzwe
        6
    tzwe  
       2016-11-17 17:36:40 +08:00 via Android
    领导毕竟是领导,胳膊拗不过大腿。
    Yourdaye
        7
    Yourdaye  
       2016-11-17 17:37:24 +08:00
    bombless
        8
    bombless  
       2016-11-17 17:38:08 +08:00
    一般项目都会为了各种无聊的理由做一些 suboptimal 的选择的,这个只是其中一例而已, 233
    jianghu521
        9
    jianghu521  
    OP
       2016-11-17 17:38:47 +08:00 via iPhone
    返回 200 到是简单!为什么 不能按照 http 标准来呢?正在努力推进!
    jianghu521
        10
    jianghu521  
    OP
       2016-11-17 17:40:30 +08:00 via iPhone
    @tomczhen 是这样的!👽👽
    Ouyangan
        11
    Ouyangan  
       2016-11-17 17:40:34 +08:00
    我倒是支持都返回 200 , 响应体中 data ,code,msg . code 用来做校验字段 ,msg 做提示信息
    6IbA2bj5ip3tK49j
        12
    6IbA2bj5ip3tK49j  
       2016-11-17 17:40:42 +08:00   ❤️ 6
    ISP 劫持非 200 怎么办?
    misaka19000
        13
    misaka19000  
       2016-11-17 17:41:06 +08:00
    1 楼已经给出了解决方案了
    abelyao
        14
    abelyao  
       2016-11-17 17:41:17 +08:00
    jarlyyn
        15
    jarlyyn  
       2016-11-17 17:42:09 +08:00
    直觉 nginx 可以直接处理掉
    murmur
        16
    murmur  
       2016-11-17 17:43:04 +08:00 via Android
    不错了,我们系统的所有错误都是 404
    jianghu521
        17
    jianghu521  
    OP
       2016-11-17 17:44:42 +08:00
    HTTP 状态码已经有语义了。既然选择了 Rest API 就要按照标准来.
    xiaotianhu
        18
    xiaotianhu  
       2016-11-17 17:46:34 +08:00
    @xgfan 正解啊!运营商这么没节操 劫持太正常了
    都 200 它还能好点
    jianghu521
        19
    jianghu521  
    OP
       2016-11-17 17:46:50 +08:00
    统计一下 大家都是返回 200 还是 按照 http status 来返回的. 谢谢大家
    abelyao
        20
    abelyao  
       2016-11-17 17:49:36 +08:00
    @jianghu521 个人还是支持业务状态返回 200 再加 status 表示业务状态,如果把业务状态也放在 http status 中,请求封装不太好统一处理。假如前端请求删除一个不存在的资源,也返回 http 404 吗?
    jianghu521
        21
    jianghu521  
    OP
       2016-11-17 17:50:13 +08:00 via iPhone
    @abelyao 删除成功返回 204
    abelyao
        22
    abelyao  
       2016-11-17 17:50:37 +08:00
    @jianghu521 不存在的资源
    hanfeng3015
        23
    hanfeng3015  
       2016-11-17 17:51:07 +08:00
    我觉得 http status 都返回 200, 也没什么问题啊, 说明网络是正常的,这样可以自己定义 code 来表示请求的数据的状态,可扩展性比较好,可以针对每类请求实体定义状态码。。。
    jianghu521
        24
    jianghu521  
    OP
       2016-11-17 17:51:33 +08:00 via iPhone
    @abelyao 不存在返回 404 代表资源不存在
    Zzzzzzzzz
        25
    Zzzzzzzzz  
       2016-11-17 17:52:22 +08:00   ❤️ 1
    不走 ssl 的话你领导说的对
    falcon05
        26
    falcon05  
       2016-11-17 17:52:50 +08:00 via iPhone
    返回 200 也可以理解,国内有些运营商或者浏览器会劫持非 200 响应
    jianghu521
        27
    jianghu521  
    OP
       2016-11-17 17:53:04 +08:00 via iPhone
    @Zzzzzzzzz 使用 https
    abelyao
        28
    abelyao  
       2016-11-17 17:56:51 +08:00
    @jianghu521
    那就不好区分是请求地址不存在,还是要操作的资源不存在咯。
    就随便举个例子,代表我个人的想法,不想上纲上线的讨论什么才是唯一的正确答案,毕竟这也跑题了
    xdazz
        30
    xdazz  
       2016-11-17 18:03:03 +08:00
    @hanfeng3015 都能返回 http status 了,说明网络肯定是正常的,网断了你都拿不到响应。

    具体怎么做,没独挡一面的实力下就听领导的。
    rogerchen
        31
    rogerchen  
       2016-11-17 18:04:34 +08:00
    程序员搞原教旨主义是没有钱途的
    allenshi
        32
    allenshi  
       2016-11-17 18:05:16 +08:00
    我做的项目都是返回 200 , 业务状态另外定义返回的 code 。
    jianghu521
        33
    jianghu521  
    OP
       2016-11-17 18:06:38 +08:00
    @xdazz 和领导讲了很多, 但是不听啊. 没有办法了。
    ty89
        34
    ty89  
       2016-11-17 18:06:38 +08:00   ❤️ 1
    你们领导说都返回 200 是有原因的
    考虑到我国国情,很多路由器是会拦截一些状态码的,比如某米路由器,所以全部返回 200 ,通过返回数据包中的字段来区分,没毛病。

    另外,标准这东西,尽可能去遵循就行了,没必要那么死板。
    learnshare
        35
    learnshare  
       2016-11-17 18:06:50 +08:00
    没有话语权就忍着,忍不住就撂挑子
    odirus
        36
    odirus  
       2016-11-17 18:07:08 +08:00
    各有各的好处,程序就是用来解决问题的,生搬硬套某种标准,有些时候真的很难做

    同上面,我见过不止一个客户端程序员把业务逻辑放在 http success 回调函数里面,也就是说 HTTP status code = 200 的情况下才会处理业务逻辑。
    huanglexus
        37
    huanglexus  
       2016-11-17 18:11:19 +08:00
    你是不是没有遵循公司的 api 设计规范而自己强行套用所谓的 REST 标准?
    knightlhs
        38
    knightlhs  
       2016-11-17 18:11:21 +08:00
    考虑国内的网络环境 这个不是啥大问题 非 200 的被劫持很严重
    jianghu521
        39
    jianghu521  
    OP
       2016-11-17 18:18:04 +08:00
    @ty89 谢谢
    jianghu521
        40
    jianghu521  
    OP
       2016-11-17 18:19:19 +08:00
    @huanglexus 一直是规范的. 这么换了领导. 要重构嘛!
    jianghu521
        41
    jianghu521  
    OP
       2016-11-17 18:21:28 +08:00
    谢谢大家了🙏. 个人只是觉得既然有标准就要按照标准来. 大家都要进步, 成长的!
    abelyao
        42
    abelyao  
       2016-11-17 18:22:24 +08:00
    @odirus C# / .net 的 HttpWebRequest 如果返回的不是 2xx 状态,直接抛出 WebException ,这时候就需要在网络异常中处理业务异常,蛋疼得要命
    iyangyuan
        43
    iyangyuan  
       2016-11-17 18:22:49 +08:00   ❤️ 9
    HTTP 的状态码理解为[通信状态]
    数据中的状态码理解为[业务状态]
    darrenfang
        44
    darrenfang  
       2016-11-17 18:26:47 +08:00 via iPhone
    @abelyao 所以都返回 200 ,在响应中的 code 字段写业务状态
    abelyao
        45
    abelyao  
       2016-11-17 18:28:17 +08:00
    @darrenfang 是的…
    owlsec
        46
    owlsec  
       2016-11-17 18:46:22 +08:00
    用 200 ,领导说啥就是啥,轮不到你说话。程序员就有一点不好就是「爱教育人」。(我也是这样)
    jianghu521
        47
    jianghu521  
    OP
       2016-11-17 18:55:02 +08:00 via iPhone
    @owlsec 没有教育他!😿😿
    buru
        48
    buru  
       2016-11-17 19:07:02 +08:00
    我们公司用这种
    版本 2 : 成功和失败执行 head Status Code:2xx

    json {"code":"0","message:"信息","data":{}}
    有什么问题吗?
    nooper
        49
    nooper  
       2016-11-17 19:13:23 +08:00 via iPad
    swagger restapi standard
    dantangfan
        50
    dantangfan  
       2016-11-17 19:14:37 +08:00
    @iyangyuan 正解
    forestyuan
        51
    forestyuan  
       2016-11-17 19:15:55 +08:00
    我想 Restful API 的规则肯定没有考虑到非 200 被劫持的问题,当然了这个是天朝特色。
    laoyuan
        52
    laoyuan  
       2016-11-17 19:16:29 +08:00
    资瓷 200 ,解一个 json 就行了,如果得到的不是 json ,再看 http status 是不是服务出问题了
    heimeil
        53
    heimeil  
       2016-11-17 19:21:44 +08:00 via Android
    @xgfan 想想还真是会有这种情况,学到了。
    z3897421
        54
    z3897421  
       2016-11-17 19:23:39 +08:00
    一定是因为 200 是绿色的 对不对~
    ck65
        55
    ck65  
       2016-11-17 19:29:53 +08:00 via iPhone
    刚被改成全 200 。没办法。
    用户水平参差不齐,有的这辈子还不知道有 status code 这说,有的是不会实现解析或嫌麻烦。
    反正多数项目都是一棒子的买卖,坚持标准的人获得了事实上的孤独。
    Adia
        56
    Adia  
       2016-11-17 19:32:12 +08:00
    666 ,这是最气的
    jianghu521
        57
    jianghu521  
    OP
       2016-11-17 19:35:12 +08:00 via iPhone
    @ck65 是的 说的太对了!一开始 android 不会拿到 error 的信息!直接扔给他 http.getErrorStream()!拿到了错误的 json 数据!
    xinyewdz
        58
    xinyewdz  
       2016-11-17 19:36:43 +08:00
    我一般使用业务状态码, http 200
    romisanic
        59
    romisanic  
       2016-11-17 19:45:17 +08:00
    如果是业务状态码,个人支持全部返回 200 ,然后通过 data 中字段来判断做后续逻辑
    romisanic
        60
    romisanic  
       2016-11-17 19:49:27 +08:00
    @iyangyuan 支持。同时感觉把通信状态跟业务状态混在一块也是够蛋疼的
    cjyang1128
        61
    cjyang1128  
       2016-11-17 19:49:34 +08:00
    我对 Rest 的理解是这只是个建议,往上面靠就行了,其实 status 返回 200 ,然后错误都用 error_code 表示,对客户端来说解析起来十分友好。 [做开放平台有感, rest 是一种思想
    good90
        62
    good90  
       2016-11-17 19:57:25 +08:00
    偶们都是 http status 返回 200 ,通过结果 ret 值表示业务 error
    Sunyanzi
        63
    Sunyanzi  
       2016-11-17 21:08:41 +08:00
    帖子里居然大部分都是全 200 的 ... 那这么看起来我是异类咯 ...

    我的核心 API 是返 4xx / 5xx 的 ... 使用自签 SSL 双向认证 ... 所有后台和 APP 端都接这个 API ...

    Web 端特殊一点 ... 前置了一个同域 Proxy 把所有返回再封一层变成全 200 ...

    这么做有明确目的是为了防止每次都多一个跨域请求和 40x 状态码被拦截 ...

    我不觉得为了妥协这两点就该改变整个 API 体系的设计思路 ...

    换言之一个 HEAD 请求判断状态码能搞定的事情为什么还要用先 GET 再解析判断返回 ..?
    jianghu521
        64
    jianghu521  
    OP
       2016-11-17 21:11:52 +08:00 via iPhone
    @Sunyanzi 终于等到知己了!
    liuyao729
        65
    liuyao729  
       2016-11-17 21:20:44 +08:00 via iPhone
    😂
    loading
        66
    loading  
       2016-11-17 21:22:33 +08:00 via Android
    一般都返回 200,表示服务器正确响应。
    返回结果 json 里面有 status 字段,表示这个 api 的返回状态。
    Sunyanzi
        67
    Sunyanzi  
       2016-11-17 21:24:14 +08:00   ❤️ 1
    @jianghu521 嘛 ... 知己归知己 ... 如果还不能像我一样独断专行说什么就是什么还是听领导的吧 ...

    我的这个规范也是个人喜好 ... 便于阅读节省流量和逼格高什么的也就只能说给自己听听 ...

    用户才不会管你用什么返回他们只要能用就行了 ... 之所以能推下去只是因为我的权力摆在这里 ...

    所以说领导都是对的 ... 如果你觉得领导不对就再看一遍这句话 ...
    Sight4
        68
    Sight4  
       2016-11-17 21:31:44 +08:00
    前端的一般是 200 ,后端接口互通才是 REST ,毕竟前端有很多坑,加上开发很参差,要全程 rest 不容易。再者,有时候 http 的错误码是不够用的,或者说,不知道用那个表示更好。在搞了很多个前后端分离的项目后,最后全部都妥协成 200 了
    izoabr
        69
    izoabr  
       2016-11-17 21:33:11 +08:00
    @cxbig 深表同感
    Phariel
        70
    Phariel  
       2016-11-17 21:34:21 +08:00 via Android
    要么忍要么狠要么滚 你不能忍 狠过了也没用 那么。。。
    izoabr
        71
    izoabr  
       2016-11-17 21:38:07 +08:00
    其实开始我也有点纠结,因为 Http Status Code 是协议状态结果,而不是我应用(业务)流程结果,不一样啊,所以不能共用。
    你说我请求一个 http ,它能正常返回呀,所以是 200 ,只是业务权限的限制,那也不能 403 呀,你说对吧。
    后来想想确实也是这么回事,反正大家约定一个标准,约定一个行径就好了,没必要纠结
    phithon
        72
    phithon  
       2016-11-17 21:38:08 +08:00
    我也是全 200 了。。。我抗议过,无效 23333
    其实我后来都快说服他了,但想想已经写好了,改来改去麻烦,就没改。
    其实改起来也方便,我用的 django rest framework ,自己写了个错误处理,把状态码都设置成 200 了。。。
    zhs227
        73
    zhs227  
       2016-11-17 21:38:32 +08:00
    原来都是返回 4xx,5xx ,后来和别人对接争论太多,都说我 SB 。现在都不争了,直接返回 200 了
    公说公有理,婆说婆有理。 RESTFUL 虽好,但要完整的遵守还是很困难。
    wizardoz
        74
    wizardoz  
       2016-11-17 22:12:06 +08:00
    我也给公司做了一个 Restful 的 API ,经常被做 APP 的问道你这个返回 204 是啥啊?成功不是 200 吗?能不能改成 200 啊?
    jon
        75
    jon  
       2016-11-17 22:24:41 +08:00
    搞啥 restful api 啊,搞搞普通 http api 得了
    jianghu521
        76
    jianghu521  
    OP
       2016-11-17 22:34:33 +08:00 via iPhone
    @Sunyanzi 这样的领导棒!👍🏿👍🏿
    jianghu521
        77
    jianghu521  
    OP
       2016-11-17 22:36:03 +08:00 via iPhone
    @zhs227 是的 人家觉得你很... 真是无语
    jianghu521
        78
    jianghu521  
    OP
       2016-11-17 22:36:36 +08:00 via iPhone
    @wizardoz 是的! 加油吧
    invalidtoken
        79
    invalidtoken  
       2016-11-17 22:42:34 +08:00 via iPhone
    @ty89 那个特性很早就被远程禁用了,你想开都不行
    otakustay
        80
    otakustay  
       2016-11-17 23:12:26 +08:00 via iPad
    支持全部 200
    zhenhang
        81
    zhenhang  
       2016-11-17 23:20:42 +08:00
    @forestyuan 加上 https 就不会这样啦
    orvice
        82
    orvice  
       2016-11-17 23:22:31 +08:00
    虽然说 rest 比较清真,某些情况下是挺有用的,比如 200 在去解析 data ,有些情况下 2xx 既然表示成功就无需再去解析 json 之类的,然后 4xx , 5xx 就只需要解析错误类型,但是,清真不一定符合基本法啊。

    有些端的人不返回 200 就以为是请求失败,领导只认 200 什么的。


    如果 lz 真的很在意清真,可以让 client header 加个啥,然后程序上根据 header 来看是否要用 status code 表成功失败,还是统一 200 在返回一个 code 继续判断咯。
    konakona
        83
    konakona  
       2016-11-18 00:54:11 +08:00
    @loading 我也是这样的。
    一般都返回 200 ,规范上如果有需要就返回 4xx 和 5xx 。只不过这样一来客户端那边( js 、 ios )其实要做的事就稍微多一些。多了一道 header 解析,虽说封装好了用着也舒服,问题是又跟真的 4xx 和 5xx 没法区分开。

    比如服务器真的挂了,或者接口访问的地址已经超出了服务端框架的范围,返回的 400 等。就很难区分出来,要做很多 null 判断。
    SoloCompany
        84
    SoloCompany  
       2016-11-18 01:23:49 +08:00
    支持只使用 200
    支持只使用 GET+POST

    Rest 只是个规范建议并不是一个协议
    何必让 HTTP 和业务捆在一起
    设计动词的时候,还要考虑怎么和 HTTP 的动词对上
    设计返回码的时候,还要考虑和 HTTP 返回码对上
    完全没有必要

    这么原教旨 HTTP 主义的话你干嘛不用 DAV 协议提供服务呢

    当然,要求重构是另一回事,但这有难度吗?用封装代替重构不就完了?
    你说你用的框架不够灵活不支持封装?
    那你自己在更高的 Service 层做 filter 啊。
    应用服务还是不支持的话写个 ngix 扩展也不是什么难事吧
    tofishes
        85
    tofishes  
       2016-11-18 02:37:42 +08:00
    http status 始终返回 200 , data.code 用于表达你想要的 status ,比如 data.code = 404, data.code = 401.
    挺好,没觉得不适。
    http status 应该表示服务的状态,而非数据的状态。
    只要服务正常,返回 200 不是应该的吗?
    jianghu521
        86
    jianghu521  
    OP
       2016-11-18 07:33:05 +08:00 via iPhone
    @SoloCompany 谢谢 代码很好写!
    huijiewei
        87
    huijiewei  
       2016-11-18 07:38:54 +08:00 via iPhone
    @konakona 这种情况很简单,根据 content-type 判断
    cyr1l
        88
    cyr1l  
       2016-11-18 07:40:59 +08:00 via iPhone
    领导也需要成长。
    scusjs
        89
    scusjs  
       2016-11-18 08:59:29 +08:00
    我们上线的应用正在要求下线改包名,这个月第三次 //手动微笑
    killerv
        90
    killerv  
       2016-11-18 09:07:40 +08:00
    Restful 只是一种编码规范,没有必要非得遵循,我见过很多公司接口中的键名命名不规范,也没见出了大问题,至于状态码全部 200 是有道理的,有些 isp 会劫持非 200 。纠结这些东西真的没必要。
    yellowV2ex
        91
    yellowV2ex  
       2016-11-18 09:11:52 +08:00
    因为 http status 不够用啊,比如微信的 API ,几十个原因和不同的提示以及参数返回,完全靠 http status 怎么行。标准不是说不好,但也好考虑自己的应用场景,生搬硬套非要遵循标准有时候确实比较痛苦,何况这个标准已经多少年了,互联网和程序发展这么快,同理参考各种框架的使用。

    当然遵循标准大家可以免沟通直接默写,其实最后还是要看使用场景和需求,没有一定的对错之分。
    wyntergreg
        92
    wyntergreg  
       2016-11-18 09:14:20 +08:00
    REST ful 不是目的

    只是一个手段

    就像语言之于工具

    如果你会某一门语言,不代表你是程序员,你只是个写 java 的,写 php 的,写 js 的

    就像你会 REST ,那你只是个写 REST 的,称不上是写 API 的
    StevenTong
        93
    StevenTong  
       2016-11-18 09:22:05 +08:00
    我司就是遵循 REST 规范的
    chocotan
        94
    chocotan  
       2016-11-18 09:25:59 +08:00
    返回 200 再加 status 表示业务状态 +1
    目前我们跟某鸟以及大多合作平台对接 都是这样的
    lrh3321
        95
    lrh3321  
       2016-11-18 09:28:03 +08:00
    我是支持 大部分情况都 状态码是 200 的。

    但是,我觉得部分情况 405 和 404 还是要允许。

    部分 404 改用 错误码来代替, 操作成功 错误码为 0 。
    tidewind
        96
    tidewind  
       2016-11-18 09:30:01 +08:00
    你去尝试推动下加 SSL 证书的事情,不然你很难说服你的领导
    chinajik
        97
    chinajik  
       2016-11-18 09:33:11 +08:00
    @iyangyuan 是这个道理
    jianghu521
        99
    jianghu521  
    OP
       2016-11-18 09:40:05 +08:00 via iPhone
    @tidewind 现在就是 https
    just4test
        100
    just4test  
       2016-11-18 09:40:31 +08:00
    直接上 HTTPS ,解决一大片劫持问题。光用 200 绕过去后面还有一队坑等着你。

    @Sunyanzi 能详细说说吗?
    - “使用自签 SSL 双向认证” 在什么场景下使用双向认证?
    - “ Web 端特殊一点 ... 前置了一个同域 Proxy 把所有返回再封一层变成全 200 ” web 和 api 使用不同的顶级域名吗?为什么不考虑用 https 呢?

    谢谢!
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2840 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:20 · PVG 20:20 · LAX 04:20 · JFK 07:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.