我正在尝试使用Grape仅使用Ruby对象创建API。我不想使用数据库/ Rails / ActiveSupport / etc - 只是Rack,Ruby和Grape。
我已为Directory
定义了一个我想通过API进行交互的类。因此,Directory#sort_by("last_name")
会返回JSON数据,其中包含People
中Directory
个对象的列表。我还有一个方法Directory#create_person(attributes)
,它接受一个字符串并使用它将Person
个对象添加到Directory
。该目录在创建时填充了人员。
我是使用Rack和Grape的新手,所以我不确定在哪里/如何创建我的Directory
对象,并通过我的Grape API类中的GET / POST来访问它。在这个类中使用一个类变量似乎有效,即:
module API
class DirectoryAPI < Grape::API
format 'json'
@@directory = Directory.new("1.txt", "2.txt", "3.txt")
get 'last_name' do
@@directory.sort_by("last_name")
end
end
end
但使用类变量似乎错了。是否有更好/更清晰的方法来创建我的Directory
对象?也许在我的config.ru
文件中?或者我可以通过Directory
内部的类方法来实现吗?
答案 0 :(得分:1)
您要找的是singleton:
通常,单身人士用于集中管理内部或外部资源,并为他们提供全球访问权限。
不幸的是,Ruby对单身人士的表现并不好。但是你可以使用仅由类方法组成的&#34;类,#34;这个article中倡导的第二个战略。
我相信您正在处理我几个月前完成的编码挑战。在我的回答中,我使用了一个仅由类方法组成的&#34;类#34;叫API::Store
。这是rspec -fd
的输出:
API::Store
::add
adds record to store
appends data line to file
::has_line?
instantiates a record from the data line
without the record in the store
should equal false
with the record in the store
should equal true
::new
should raise NoMethodError
::records
with original file
on initial access
should eq Records
on subsequent access
should eq Records
when file replaced
should eq OtherRecords
Finished in 0.07199 seconds (files took 2.68 seconds to load)
9 examples, 0 failures
请注意,Store
无法实例化;如果你尝试,它会抛出一个NoMethodError
。但这不是问题。在Grape端点中,您可以调用Store.records
来访问数据。
至于记录的排序,这应该在另一个类中完成。为什么Store
或Directory
要对其文件中的数据进行排序?
最后,您询问了初始准备的位置(当然不是初始化)。您可以在config.ru
中准备单件,以便在应用程序启动时准备就绪:
# config.ru
# load application code here
file = File.open('data/records.txt', 'a+')
at_exit { file.close }
API::Store.file = file
run API::Base
挑战instructions说&#34;您可以使用完成它所需的任何资源,&#34;所以大概是允许在Stack Overflow上询问。如果您正在为求职申请进行此项挑战,请在提出问题时提及,因为对于那些接听通知的人来说,这只是公平的。在你的采访中也提到你在SO上得到了帮助是明智的。祝你好运,编码愉快。
答案 1 :(得分:0)
我在您的示例中看到的主要问题不是完全使用类变量,而是在API控制器代码中实例化内联数据。理想情况下,数据应该更加自包含,因此您可以从代码中的其他位置访问完全相同的数据。如果您创建类似于轻量级数据访问模块的API,那么您将在路由控制器中使用熟悉的模式 - 如果需要,也可以轻松迁移到使用SQL或其他数据存储。
有许多有效的方法,但我可能会创建一个新的单例对象来表示您的数据源,并将其连接到您的硬编码数据,就像它是表格一样。这里的最终结果有点像使用Sequel(但你可以按照你喜欢的任何其他模式):
<强> inline_data.rb 强>
module InlineDB
TABLES = Hash[
:directory => Directory.new("1.txt", "2.txt", "3.txt")
]
def self.[] table_name
TABLES[table_name]
end
end
<强> app.rb 强>
require_relative 'inline_data' # actual path may be more structured
module API
class DirectoryAPI < Grape::API
format 'json'
get 'last_name' do
InlineDB[:directory].sort_by("last_name")
end
end
end