我已经使用GRAPE gem创建API端点。
对于简单的用例,让我们考虑一下,当点击我的Web服务时,我点击了另一个第三方REST API,并且获取了一些值并将这些值分配给一个或两个变量。例如variable1,variable2
这些值经常从第三方API更改,因此我还必须不断更新变量值,当在API代码中使用它或将其作为参数传递给方法时,一切都很好。
但是我很少有控制器应该使用更新的变量/应该使用更新的值。
目前我要做的是:
class Api < Grape::API
version 'v1'
format :json
helpers MyProject::Config
resources :foo do
get do
variable1 = #hit third party URL
$global_variable1 = variable1
end
end
end
在控制器中:
class SampleController < ApplicationController
def method()
some_calc = $global_variable1 + other_variable
end
end
现在这可以正常工作,除了全局变量之外,还有其他更好的方法可以使用吗? 还是我们可以这样:
Rails.application.config.variable1 = variable1
哪个是前进的更好方法?
我曾尝试在API类中设置@instance变量,但这在控制器方法中访问时会给出空字符串。
@variable1 = ""
def self.variable1
@variable1
end
并像ClassName.variable1
一样访问它任何人都可以提出更好的前进方向吗?
答案 0 :(得分:1)
理想情况下,您将在启动期间的某个时间创建一个用于保存这些参数的对象,然后通过某种形式的依赖注入将单个实例注入到需要它们的每个类中,但是由于我不知道任何常用的依赖注入方案对于铁轨,我建议这两种选择。
有些人不喜欢单例,但是您可以将它们存储在单例类中。
require 'singleton'
class APIParams
include Singleton
attr_accessor :v1, :v2
end
APIParams.instance.v1 = 3
puts APIParams.instance.v1
这可能有些过分,但是您也可以为其创建模型并将其存储在数据库中。如果您有多个资源需要存储同一组变量,例如api_key
和或令牌,这可能很有用。
class APIResource < ActiveRecord::Base
# you probably would want some `belongs_to`, has_a relationships here to associate these with the models used in your controllers.
end
由具有类似字段的表支持
create_table "api_resources", force: :cascade do |t|
t.string "name",
t.string "api_key",
t.string "token"
end
答案 1 :(得分:1)
全局变量是恕我直言的坏主意。这或多或少与单例相同。 您将如何更新变量,谁来做?什么时候?您如何检查是否过期?如果您有多个红宝石过程并且它们使用不同的值怎么办?
这听起来像是缓存和从缓存读取的服务的好用例。
class ParameterService
def get(parameter_name)
if parameter is not in cache or expired
read from external service and store in cache
end
return value from cache
end
end
缓存可能类似于Redis,数据库,Memcached。