简短的回答是,这Grape
与您的想法不太一样,并且属性变量MyProject::Api
不是您的新 Web 服务的前进方向。然而,这是一个有趣的问题,值得探索为什么会这样。
如果您在块puts self.inspect
内添加 a 并使用 运行,当您调用路由时,您应该会看到它实际上是一个对象。此外,无论您尝试对实例变量做什么,对于每个请求,它们总是以相同的状态开始。这是因为将您的路由定义转换为准备好的对象,将大量定义数据和设置放入一个可快速访问的表单中(这样就不会在每个请求中都计算出来)。最终,在每个请求中, 包括您的块(以及您为路由定义的其他详细信息)在内的匹配对象在被调用之前都会被复制,这意味着在请求之间不会维护该状态。resources :foo
rackup
self
Grape::Endpoint
Grape
Grape::Endpoint
Grape::Endpoint
这可能看起来很复杂,但大多数涵盖 Web 服务请求的框架都会做类似的事情。通常,您不希望请求处理状态在请求之间持续存在。具有更大范围的框架——例如 Rails——有地方为你规划了更多的持久性数据。葡萄没有这个定义,这有其优点和缺点。一个明显的优点是您可以更自由地使用您希望使用的任何其他数据持久性方法。
23tux 的回答会立即为您整理好加载配置。虽然我不完全确定@@data
端点块如何访问(它甚至可能在变量周围创建一个闭包)。
从长远来看,您应该考虑将配置管理移出您的MyProject::Api
课程,并通过 Grape 的helpers
方法将其作为一个模块包含在内(如果您有兴趣,我很乐意提供一个示例)。
编辑:基于您当前代码的示例,但将配置管理移动到单独的模块:
require 'grape'
require 'json'
require "yaml"
module MyProject
module Config
CONFIG_FILE = "./config.yml"
@@data = nil
def config
@@data ||= YAML.load( File.open( CONFIG_FILE ) )
end
end
class Api < Grape::API
rescue_from :all
prefix 'api'
version 'v1'
format :json
helpers MyProject::Config
resources :foo do
get do
config
end
end
end
end
这在结构上比 23tux 的答案更进一步,但仍然没有完全区分存储(和缓存等)与 api 访问的关注点。随着您向更复杂的 Web 服务迈进,您将希望保持 Grape 路由定义简单,只使用少量管理或操作数据的逻辑 - 嗯,至少从块中直接看到。
Grape 定义与其他可能管理配置、日志记录、身份验证和其他服务的 gem 之间链接的一种方法是通过 Grape 的helpers
方法。Grape 还为常见任务提供了一些内置的辅助方法。
用于将共享函数添加到 Grape的主要例外helpers MyModule
是当您想要管理来自核心应用程序的显示数据对象(也称为“模型”)时。为此,您有几个选择,但grape-entity
gem 和present
方法并不是一个糟糕的起点。