2

我正在为一个已经存在的 Rails 应用程序开发一个使用 ruby​​ 和 Sinatra 的 API。我已经分离了应用程序(没有安装逻辑),因此这些应用程序是单独部署的。在生产中,我使用 nginx 作为两个应用程序的代理服务器,它使用域匹配来分派到正确的应用程序。

我也在对我的 API 进行版本控制。目前我正在 Sinatra 应用程序本身中执行此操作,通过覆盖获取、发布、过滤器等调用的方法,因此,无论您应用哪个字符串或正则表达式规则来匹配请求 uri,它们都会有他们添加之前的版本控制:

# matches /v0.1/resource/:id
get "/resource/:id" ....

这样做的缺点是总是必须至少匹配 url 的开头,首先 / 包含,否则将无法正确添加版本号。不仅如此,这意味着我也只为每个应用程序匹配一个 API 版本。

我仍在开发第一个版本,因此随着 API 的版本升级,现在有时间找出继续前进的最佳策略。我看到了两种可能的策略:

  1. 让一切都像 Rails(正如他们在 railscast 上推荐的用于 REST API 版本控制的那样)并在应用程序中始终对匹配进行版本控制:

    get "/0.1/resource/:id" do .....
    get "/0.2/resource/:id" do .....
    

    这样做的缺点是总是有两个(或更多)版本的逻辑,这使得 url 匹配逻辑更加复杂(比如,如果我想用 /\d+/resource/\d+ 之类的一个规则来匹配所有内容,那么我会在我看来,仍然必须查看版本号是否可以接受)并增加意大利面条的出现次数。

    它的优点是保持相同的部署逻辑(用当前替换最后一个版本,nginx 仅路由到一个 API,等等......)。

  2. 让 nginx 按版本分派。使用 CVS,我可以对我的代码进行版本控制。我只需要定义我想在线支持多少个版本,部署它们,然后重新排列 nginx 路由,现在将基于域+版本。

    这具有清理应用程序逻辑的优点,因为我只匹配逻辑的必要规则。使用最后一个例子:

    get "/resource/:id" do ....
    

    nginx 会负责路由到正确的应用程序。

    不过,这有一些技术上的缺点:为此,我必须更改部署策略,因为我必须选择我支持多少个 API 版本,从我的 CVS 中获取它们,然后编辑 nginx 配置,删除最后一个 API 规则,插入新规则(路由到 api.myapp.com/v1、api.myapp.com/v2...)并重新初始化 nginx。另一个缺点是现在我必须支持多个 API 代码基础,例如错误修复......这与上面相同,我只需要支持不同的版本标记代码基础。

我想知道其他人在他们的案例中是如何解决这个问题的,以及这对后续维护有何影响。

4

0 回答 0