RESTful API 设计,到底加不加 版本号? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
ericgui
V2EX    程序员

RESTful API 设计,到底加不加 版本号?

  •  
  •   ericgui 2017-08-14 17:57:56 +08:00 14242 次点击
    这是一个创建于 2985 天前的主题,其中的信息可能已经有所发展或是发生改变。

    http://www.ruanyifeng.com/blog/2011/09/restful 阮一峰认为,版本号应该放在 HTTP 请求头中

    https://juejin.im/post/59826a4e518825359c5e72d1 这个认为,API 版本号应该区分

    而且 github API,也是 URI 中带有版本号的,难道说 github 的 API 设计的不好?

    所以我怀疑 阮一峰这个问题上搞错了。

    能分享一些实际的设计 API 的经验吗?谢谢

    30 条回复    2018-09-28 11:39:11 +08:00
    acoldfox
        1
    acoldfox  
       2017-08-14 18:06:46 +08:00
    觉得这个各说纷纭,到最后是怎么方便怎么来了,我是在 url 中保留版本号的,比如 v1,v2 是独立的模块,如果版本改动太多,就另起一个新 module 跟以前的区分开,互不干扰
    cuebyte
        2
    cuebyte  
       2017-08-14 18:23:34 +08:00 via Android
    也不尽然是方不方便的问题,在后端的设计里,URL 本身就是和 controller 挂钩的,而不同版本需要不同的 controller。所以把版本号放在 URL 里是很自然的一件事。况且也更直观。
    gigantic222
        3
    gigantic222  
       2017-08-14 18:30:10 +08:00 via iPhone
    原理都一样啊本质上没区别 可能时常需要 simple request 限制 header 吧
    sampeng
        4
    sampeng  
       2017-08-14 18:35:25 +08:00
    我一般扔 header 里面。干净一点
    danielmiao
        5
    danielmiao  
       2017-08-14 18:40:07 +08:00
    习惯放在 url 上
    1.调用直观,写文档方便
    2.不同版本的相同功能接口,可以在不同的包中使用相同的 url,便于代码管理( maven 版本和 url 版本关联)。
    3.不同版本接口可以分开部署,平滑升级,通过 nginx 简单规则匹配就分派到不同的服务器上。
    lslqtz
        6
    lslqtz  
       2017-08-14 18:40:12 +08:00
    不加
    等改动的时候加,丢 header 比较麻烦
    leky
        7
    leky  
       2017-08-14 18:41:30 +08:00 via iPhone   1
    如果返回数据结构一样,个人觉得版本号在 header 会比较方便,客户端都不用改 api url,其它的倒是没什么可说的
    xiaozizayang
        8
    xiaozizayang  
       2017-08-14 18:41:57 +08:00 via Android
    我一般加路由里面
    Kilerd
        9
    Kilerd  
       2017-08-14 18:49:36 +08:00 via iPhone
    无论是对前后端来说,怎样都是一两个语句的事情。
    这个真的是怎么方便怎么来
    jarlyyn
        10
    jarlyyn  
       2017-08-14 18:52:40 +08:00
    放在 url 里。
    说请求头的,难道现在 url 不是请求头了么?
    另外, 我不是很喜欢很纯粹的 restful 接口。
    dracarysX
        11
    dracarysX  
       2017-08-14 18:59:32 +08:00
    基本就是请求头和 url 两种方案比较流行。
    不过个人感觉大多数的 API 设计都是 url 这种方案(很多大厂都是这种),这种设计更加直观,清晰。从开发方面看也是比较舒服的,不需要一直去判断请求头的版本去寻找处理函数。
    ps:阮一峰也不一定都是对的。
    lightening
        12
    lightening  
       2017-08-14 19:08:14 +08:00
    这只是 opinion,有什么对错之分么
    jameshuazhou
        13
    jameshuazhou  
       2017-08-14 19:23:05 +08:00
    两种方式都用过,放 url 中别人更不会犯错,而且放请求头中有些木有经验的还得教他怎么做。
    理论上放头中更漂亮些,但实际中还是放 url 省心些。
    sunjourney
        14
    sunjourney  
    &bsp;  2017-08-14 20:36:01 +08:00
    放 url 里 get 请求是可以缓存的, 阮老师的文章里错误不少或者在转达别人的观点因此有时候会有讲同一个内容的观点矛盾。
    janxin
        15
    janxin  
       2017-08-14 21:01:51 +08:00 via iPhone
    放头里最好有 api 网关
    mikulch
        16
    mikulch  
       2017-08-14 21:11:58 +08:00
    要。推荐楼主看看《 web api 的设计与开发》这本书。
    lrh3321
        17
    lrh3321  
       2017-08-14 21:30:14 +08:00
    放在 url 里+1

    老版的 API 可能和新版的跑在不同的 server 上
    changwei
        18
    changwei  
       2017-08-14 21:30:58 +08:00 via Android
    看了好多大厂,比如说百度,知乎之类的网站都是版本号放 url 中,这样的话测试或者发起请求都更方便,程序里面不需要额外调用各种修改请求头的 api。
    geelaw
        19
    geelaw  
       2017-08-14 21:45:03 +08:00
    如果你把 URL 看作对象的 view,就很好理解版本号放在 URL 里面的想法。这相当于是张三还是李四来看这个对象,是老人还是年轻人看这个对象的问题。
    run2
        20
    run2  
       2017-08-14 21:53:21 +08:00
    放 uri 里是为了兼容性,放 header 里貌似还不好分析跟踪-。-
    zhoulouzi
        21
    zhoulouzi  
       2017-08-14 22:07:38 +08:00
    uri 就不是请求头了吗
    qiyuey
        22
    qiyuey  
       2017-08-14 23:50:43 +08:00
    github 不是已经不再使用 restful api 了吗
    ETiV
        23
    ETiV  
       2017-08-15 03:05:48 +08:00 via iPhone
    放头里要多几个字节( x-api-version 这样),所以不放。
    libook
        24
    libook  
       2017-08-15 09:08:50 +08:00
    哪个方便用哪个,看你的架构是什么样的,以及 API 版本差异特点。

    版本区分仅限于个别 API 的话就加在 Header 里;
    版本区分是普遍的、整体的,就写在 URI 里;
    如果版本差异巨大,以至于使用完全不同的服务和集群,就写在域名里。

    通常不是做 SaaS 的话 API 版本的维护要求不是特别严格吧,所以也没必要做的冠冕堂皇,我们是每年出 1-2 个大版本,同时维护的版本只有 1-2 个,前端强制升级旧版本会直接抛弃,所以直接用域名区分了,简单有效,而且对云计算服务友好。
    zhangmiaoCHN
        25
    zhangmiaoCHN  
       2017-08-15 09:53:44 +08:00
    Facebook 的码农之前也纠结过这个问题,后来搞了一个 GraphQL 试图改善 RESTful API 的局限
    现在 Github API v4 版本已经不再使用 RESTful API 了,改用 GraphQL 去构建 API
    https://developer.github.com/v4/
    ericgui
        26
    ericgui  
    OP
       2017-08-15 12:02:48 +08:00
    @qiyuey V3 和 V4 共存,都能用
    ericgui
        27
    ericgui  
    OP
       2017-08-15 12:03:48 +08:00
    @zhangmiaoCHN V3 和 V4 共存,都能用
    qiyuey
        28
    qiyuey  
       2017-08-15 13:46:48 +08:00
    @ericgui 我的意思是,是不是你也该放弃 rest 了
    ericgui
        29
    ericgui  
    OP
       2017-08-15 21:40:25 +08:00 via iPhone
    @qiyuey RRES API 还是有很多人在用,哪能说不用就不用呢?
    derrickT
        30
    derrickT  
       2018-09-28 11:39:11 +08:00
    1. 在 header 里加 version
    2. 在请求里加 version
    3. 在 nginx 里根据 version 转发到对应的版本
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2877 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 14:11 PVG 22:11 LAX 07:11 JFK 10:11
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86