欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

APP API需要同时维护多个版本如何优雅的设计?

程序员文章站 2022-05-08 21:31:02
...

第一种形式:

Controller/V1.0.0/
-----------------/UserController.php
-----------------/UploadController.php
-----------------/********************
Controller/V2.1.0/
-----------------/UserController.php
-----------------/UploadController.php
-----------------/********************

第二种形式

Controller/
----------/UserCreateController.php
----------/UserInfoController.php
----------/UploadImageController.php
UserCreateController.php 内容如下

更多,请回答

回复内容:

第一种形式:

Controller/V1.0.0/
-----------------/UserController.php
-----------------/UploadController.php
-----------------/********************
Controller/V2.1.0/
-----------------/UserController.php
-----------------/UploadController.php
-----------------/********************

第二种形式

Controller/
----------/UserCreateController.php
----------/UserInfoController.php
----------/UploadImageController.php
UserCreateController.php 内容如下

更多,请回答

如果只是讨论的话:

第三种

客户端在做请求的时候在接口中添加ver字段,标识出请求的是哪个接口:

  • api.xxx.com/api?ver=v1&...
  • api.xxx.com/api?ver=v2&...

这种做起来比较简单也容易理解,但是在你的每个接口逻辑里面都得需要写判断版本的代码了。比如

if ver == 'v1':
  do_something_with_v1_style
elif ver == 'v2':
  do_something_with_v2_style

这样的代码看起来感觉很不舒服。

第四种

客户端在做请求的时候在HTTP HEAD里面中添加API-VERSION字段,标识出请求的是哪个接口:

  • -H "API-VERSION: v1"
  • -H "API-VERSION: v2"

这个需要统一做的事情稍微有点多,但之后的接口逻辑会比较好些。在入口的地方获取接口版本,然后把请求分发到对应版本的接口处理器上。

api(req):
  if req.HEADS["API-VERSION"] == 'v1':
    distribute_to_v1_api(req)
  elif ver == 'v2':
    distribute_to_v2_api(req)

第五种

不同版本使用不同的域名,这样:

  • v1.api.xxx.com
  • v2.api.xxx.com

域名的方式可以采用下面的两种方式:
1、不同版本的api部署成不同的应用(甚至可以部署到不同的服务器上),彼此间独立,其好处是部署的过程不会影响其他版本api的使用,并且可以减轻单台服务器的负担。
2、部署在一个应用上面,但是和第四种一样,在接口入口出分发到不同版本的接口处理器上进行处理。好处是不同版本间能够直接复用相同的功能。

最后说一下吧

我个人比较倾向于域名方式或者你的第一种(xxx.com/v1/、xxx.com/v2/):

  • 在整个产品的生命周期中接口的数目和功能可能会不停的增加,但对于某个接口而言,不会频繁的变动(修改接口的输入输出约定),而增加接口对于老的接口是没有影响的,也就不会到必须升级接口的地步(你的老app只是在用原来就存在的老接口而已,新增加的接口对它没有影响);
  • 如果你的接口变化已经到了今天v1、明天v2、后天v3的地步,那么得考虑你们一开始对产品的需求是否足够准确了(估计需要维护的接口文档也会让人头疼);
  • 不同版本接口相互独立在某种程度上限制了你,让你不会随随便便就v1、v2、v3。(当你每天都要用一个新域名的时候你自己一定会不自然的反思是不是变换太频繁了);
  • 接口版本信息能够直接在url里面体现,清晰易懂,也比较容易做接口调试(没错,给我一个Chrome就够了);
  • 不同的版本的api应用(或者接口处理器)之间彼此独立,这符合软件工程的低耦合原则。

没有很优雅的设计,只能自己考虑的长远写,接口的代码写的可扩展性高一些。App跟网站不一样,即使你发新版了还是有很高几率用户不买账不更新的。所以最好在最初设计接口的时候就想的长远些,API的URL不能随便动, 可以让手机端在请求接口的时候给你在参数中挂一个版本号,这样能区分出客户端的版本,但即使是这样搞多了代码写起来也很坑的, 所以设计核心业务的API只能考虑的比较清楚了,有些东西刚开始不做但是近期几个版本要做的话就预先留好入口,代码写的可扩展性高一些方便以后兼容,数据库中也可先预留好字段。

产品最初两版基本上都在探路,方向调整和逻辑重构是难免的,说下切身体会:痛苦的把API做了向前兼容(判断接口通信时新加的参数,没有就给默认值,有些字段值,可以靠查老数据算出来等等),测试新旧客户端访问都没问题后然后半夜4点爬起来(因为看友盟分析4点是我们产品活跃最少的时候,基本没人)改正式环境的数据库、往新表里跑数据。当时App已经有一万多用户了,白天日活还说的过去。跑着跑着发现突然有个用户在四点半的时候过来用App还产生了些数据...当时感觉有万匹*从我的小心脏上踏过,赶紧把DNS解析先暂停了, 等一切都弄后再恢复回来的。

PS:说句题外话,有一个不知名的渠道抓了我们的APK包,结果他们SEO做的还挺好,百度搜我们产品的关键字他们总是排得挺靠前,气人的是丫抓了我们1.3版本的包后半年不更新,现在我们都2.0.2了,现在在新增用户中都能看到1.3版本注册进来的用户... 从这能看出安卓App的版本更新有多难控制(在产品不强的时候不敢让用户强制更新,安卓除了小米那一派程序都不能进行静默更新)

相关标签: php php框架