我有一些带有金属端点的Engine插件,它实现了一些我打算在多个应用程序中共享的非常简单的Web服务。它们工作正常,但很明显,在本地加载它们进行开发和测试时,发送Net :: HTTP get_response消息,要求localhost从当前正在执行的控制器对象内部获取另一个页面,导致即时死锁。
所以我的问题是,Rails'(或Rack)的路由系统是否提供了一种安全使用Web服务的方法,该服务可能是也可能不是同一服务器实例下同一个应用程序的一部分,或者我是否需要破解当URI中的主机名与我自己的主机名匹配时,与render_to_string一起使用的特殊情况是什么?
答案 0 :(得分:3)
它在开发中不起作用,因为它一次只提供一个请求,并且控制器的请求被卡住了。如果需要,可以在负载均衡器后面本地运行多个服务器。我建议使用Passenger进行开发(如果您使用的是OS X,则使用prefpane。)
我建议您分离内部Web服务和使用它们的应用程序。这样您就不会复制代码,您可以轻松地单独扩展和控制它们。
答案 1 :(得分:0)
这实际上是可行的。但是,您需要确保您调用的服务不会以递归方式相互调用。
非常简单"可重入" Rack中间件可以像这样工作:
class Reentry < Struct.new(:app)
def call(env)
@current_env = env
app.call(env.merge('reentry' => self)
end
def call_rack(request_uri)
env_for_recursive_call = @current_env.dup
env_for_recursive_call['PATH_INFO'] = request_uri # ...and more
status, headers, response = call(env_for_recursive_call)
# for example, return response as a String
response.inject(''){|part, buf| part + buf }
end
end
然后在调用代码中:
env['reentry'].call_rack('/my/api/get-json')
一个非常有效的用例是在JSON中加载API响应 主页中的格式。
显然,这种技术的成功取决于复杂程度 您的Rack堆栈(因为Rack env的某些部分不希望被重用)。