在运行时使用来自另一个sinatra app的路线

时间:2013-08-16 19:41:40

标签: ruby routes sinatra rack

在现实世界中,感谢Rack :: Builder,我启动了两个sinatra应用程序,并将其中一个映射到“/ api / v1”,另一个映射到“/ ui”。

我希望映射到/ ui的应用能够利用/ api中的路由,但是, 因为它们是分开的,所以ui应用程序无法在api方面执行调用。

有没有办法通过机架从另一个应用程序的路由调用,或者我应该使用Net :: HTTP?

以下是我正在尝试做的简化示例:

#/usr/bin/ruby
require 'sinatra'

class API < Sinatra::Base
  get '/accounts/' do
    '{"json":"account_data"}'
  end
end

class UI < Sinatra::Base
  get '/accounts/' do
    # How do I get /api/accounts?
    # call "/api/accounts" obviously does not work

    # would use erb here to render accounts list in human readable form
  end
end

rack = Rack::Builder.new

rack.map "/ui" do
  run UI.new
end

rack.map "/api" do
  run API.new
end

Rack::Server.start :app => rack
exit

非常感谢!

1 个答案:

答案 0 :(得分:1)

如果这些应用程序在Rack中组合在一起,则它们没有真正的连接。什么Rack会对您已经忙碌的任何应用程序调用{​​{1}}并使用.call(env)进行响应您可以在中间执行操作并修改[status,env,body]的图层。您的机架在您映射的任何应用程序上触发env以响应该路径。被叫应用程序没有Rack中运行的概念。除非在上游填充的#call中有一个句柄,否则它也不能调用另一个应用程序。

但你必须考虑为什么你决定首先制作这两个不同的应用程序。我想这是因为可能有多个应用程序使用API​​。或者你喜欢脱钩的性质。因此,在这种情况下,您必须考虑是否需要通过Rack进行一些耦合。如果API在另一台服务器上怎么办? 2到Rack之间的任何内部链接都会破坏UI应用程序。如果您始终知道您的API将自包含在同一台计算机上,您也可以将其设为库而不进行HTTP调用。

因此即使可以从一个共同运行的应用程序调用路由,我也绝不会这样做。拥有API服务器的全部原因是要有一个解耦层。您应该通过HTTP访问该层,以便它可以在同一个盒子或世界各地使用。