Rails 请教如何设置 API 项目版本相关的路由

night_7th · 2015年10月27日 · 最后由 vkill 回复于 2015年10月28日 · 2670 次阅读

最近接手一项工作,是为部门内部使用的 JIRA 补充一些 API,原有 JIRA API 的格式是这样的:

http://jira.mycompany.com/rest/api/latest/search?jql=相关查询语句

我希望我补充的 API 的格式和原有保持一致,于是我在routes.rb中是这么设置的:

Rails.application.routes.draw do
  namespace :rest do
    namespace :api do
      namespace :v1 do
        get '/search', to: 'issues#search'
      end

      # 我希望latest自动指向v1版本下的controller处理
      match 'latest/*path', to: redirect{|params, request| "/rest/api/v1/#{params[:path]}?#{request.query_string}"} , via: :get
    end
  end
end

然而当我去调用 api 的时候,如果调用的地址格式是/rest/api/v1/search?jql=查询语句,那么返回是 200,一切 OK。 当我去调用/rest/api/latest/search?jql=查询语句的时候:

res = Net::HTTP.get_response(URI('localhost:4000/rest/api/latest/search?jql=查询语句'))

在 web 端看一切正常,也重定向到了我所希望的地址。可是由于使用了重定向,导致了返回值是 301。

可是我观察原有 JIRA API 的情况,它在调用/rest/api/latest/search?jql=查询语句的时候,http code 返回值依然是 200。

想请教一下大家,API 项目中,这种latest指向某一版本的情况是怎样实现的?

可以用 rewrite 实现

提供一个折衷的方法,需要在路由中加一个辅助方法:

Rails.application.routes.draw do

  def point_to_latest(version = "v1", path)
    to = {
      "search" => "#{version}/issues#search"
    }[path]

    return "latest/#{path}", {to: to}
  end

 namespace :rest do
    namespace :api do
      namespace :v1 do
        get '/search', to: 'issues#search'
      end

      # 我希望latest自动指向v1版本下的controller处理
      # match 'latest/*path', to: redirect{|params, request| "/rest/api/v1/#{params[:path]}?#{request.query_string}"} , via: :get
      get *point_to_latest("search")
    end
  end

end

要我,我会去 nginx 中加个 location

需要 登录 后方可回复, 如果你还没有账号请 注册新账号