关于 Restful API 版本号控制的实现选择 - V2EX
请不要在回答技术问题时复制粘贴 AI 生成的内容
remember5

关于 Restful API 版本号控制的实现选择

  •  
  •   remember5 Sep 29, 2022 3598 views
    This topic created in 1322 days ago, the information mentioned may be changed or developed.

    背景

    项目基于 SpringBoot,业务迭代较快,常有接口不向下兼容的情况,需要实现多版本的接口

    多版本实现方式

    Api 版本控制的方式:

    1. 域名区分管理,即不同的版本使用不同的域名,v1.api.test.comv2.api.test.com
    2. 请求 url 路径区分,在同一个域名下使用不同的 url 路径,test.com/api/v1/,test.com/api/v2
    3. 请求参数区分,在同一 url 路径下,增加 ersion=v1 或 v2 等,然后根据不同的版本,选择执行不同的方法。

    实际项目中,一般选择第二种:请求 url 路径区分。因为第二种既能保证水平扩展,有不影响以前的老版本

    原文链接: https://blog.csdn.net/weixin_39255905/article/details/110391515

    两种实现对比

    比较倾向 url 路径区分,如上实现@ApiVersion()

    如:test.com/api/v1/test 其中v1是版本 test是具体接口

    基于 Controller 隔离控制

    在 Contorller 层添加注解,如 @ApiVersion(1)@ApiVersion(2)

    • 请求正确的版本地址,会自动匹配版本的对应接口
    • 请求的版本大于当前最大版本时,默认匹配当前最大版本。
    • 请求的版本小于当前最小版本时,会 404
    • 请求对应的版本不存在接口(methods)时,会匹配之前版本的接口

    基于 Methods 中的注解大小控制

    在具体的 Methods 上添加注解,如 @ApiVersion(3)

    • @ApiVersion(3)自定义注解,传递参数信息表示默认最低的版本限制。

    总结

    综上所述,大家更喜欢哪种方式?

    18 replies    2022-09-30 08:46:54 +08:00
    wonderfulcxm
        1
    wonderfulcxm  
       Sep 29, 2022 via iPhone
    WordPress 的 rest API 是第二种,可能是因为它面向的用户什么水平的都有,为了简单,不用考虑再加一个域名。
    remember5
        2
    remember5  
    OP
       Sep 29, 2022
    @wonderfulcxm #1 是的,个人也比较倾向 url 路径区分
    penzi
        3
    penzi  
       Sep 29, 2022 via Android
    你说的 1 和 3 根本没有一个成熟的 api 这么做吧,都是 2
    lkk
        4
    lkk  
       Sep 29, 2022
    2 吧。1 还要多来一个 DNS 策略
    gxvsko
        5
    gxvsko  
       Sep 29, 2022   1
    https://restfulapi.net/versioning/
    还可以放到 Accept header 头里
    wolfie
        6
    wolfie  
       Sep 29, 2022
    一般大厂对外 openapi 都是 2
    hsymlg
        7
    hsymlg  
       Sep 29, 2022
    做契约测试,类似 pact ,不用的接口及时过期或清理。git 本身就是控制版本的,再在接口上面加上版号,自我折磨嘛。
    otakustay
        8
    otakustay  
       Sep 29, 2022
    1 涉及跨域太要命了,3 涉及参数拼接太麻烦了,基本全是 2 或者 header 传 X-API-Version
    julyclyde
        10
    julyclyde  
       Sep 29, 2022
    如果有条件的话,用域名最好
    等到将来,你都 v 好几了,还有几个赖着不走的 v1 客户端,可以直接掐了他们的服务,以绝后患

    如果用路径的话,赖着不走的旧版本客户端,无论如何都会给你带来点儿负担的

    querystring 显然是错误的,别想了
    remember5
        11
    remember5  
    OP
       Sep 29, 2022
    @maggch97 #3
    @lkk #4
    @wolfie #6
    @otakustay #8
    是的,个人也非常偏向于 2 ,且 SpringBoot 更改起来也比较方便
    remember5
        12
    remember5  
    OP
       Sep 29, 2022
    @gxvsko #5 这个不错,学习了,考虑结合项目改造,选择了路径区分
    @Oktfolio #9 同上,感谢
    remember5
        13
    remember5  
    OP
       Sep 29, 2022
    @julyclyde #10 是的,域名的话,考虑到会对接三方以及跨域的风险,不过域名可以起到绝对的隔离,querystring 只是一种想法,并不成熟,也不理想。
    alen0206
        14
    alen0206  
       Sep 29, 2022
    /api/v2
    humpy
        15
    humpy  
       Sep 29, 2022 via iPhone
    针对主楼的内容,直接 requestmapping 的 path 写上 v1 、v2 就行了,为什么还要发明一个注解呢
    remember5
        16
    remember5  
    OP
       Sep 29, 2022
    @hsymlg #7 App 业务中,需要兼容低版本,业务角度不属于过期代码
    remember5
        17
    remember5  
    OP
       Sep 29, 2022
    @humpy #15 感谢提醒,上面忘记补充了,直接在 ReuqestMapping 中添加 /v1 /v2 的确更加直观,但注解方式更加灵活,可控制最低版本限制,版本继承等优点。
    xuanbg
        18
    xuanbg  
       Sep 30, 2022
    不在单个接口 url 上面区别版本的话,不知道有多少坑。。。。
    About     Help     Advertise     Blog     API     FAQ     Solana     986 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 83ms UTC 22:24 PVG 06:24 LAX 15:24 JFK 18:24
    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