抱歉,还没有人回复这个问题,目前内置的 json 处理程序有点坏,它会手动构建 uri 当它应该从数据集中使用它时,你可以用类似下面的东西来实现你想要的:
注意:我只是调用.dataset.uri
来显示将要查询的 URI 示例,因为我没有在本地运行的兼容 API。
注意:除了使用库之外,您可能还想使用自定义适配器。
require 'bundler/inline'
gemfile(true) do
gem 'rom'
gem 'rom-http'
end
class MyJSONRequest
def self.call(dataset)
uri = dataset.uri
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme.eql?('https')
request_class = Net::HTTP.const_get(ROM::Inflector.classify(dataset.request_method))
request = request_class.new(uri.request_uri)
dataset.headers.each_with_object(request) do |(header, value), request|
request[header.to_s] = value
end
http.request(request)
end
end
class MyJSONResponse
# Handle JSON responses
#
# @param [Net::HTTP::Response] response
# @param [Dataset] dataset
#
# @return [Array<Hash>]
#
# @api public
def self.call(response, dataset)
Array([JSON.parse(response.body, symbolize_names: true)]).flatten(1)
end
end
ROM::HTTP::Handlers.register(
:my_json,
request: MyJSONRequest,
response: MyJSONResponse
)
rom = ROM.container(:http, uri: 'http://localhost:8000/api', handlers: :my_json) do |conf|
conf.relation(:users) do
schema('v1/users') do
attribute :id, ROM::Types::Integer.meta(
primary_key: true
)
attribute :name, ROM::Types::String
end
def by_id(id)
append_path(id)
end
def offset(offset)
add_params(start: offset)
end
def limit(limit)
add_params(size: limit)
end
end
conf.relation(:posts) do
schema('v1/posts') do
attribute :id, ROM::Types::Integer.meta(
primary_key: true
)
attribute :name, ROM::Types::String
end
def by_user(user_id)
with_options(
base_path: 'v1/users',
path: "#{user_id}/posts"
)
end
end
end
users = rom.relations[:users]
posts = rom.relations[:posts]
users.offset(0).limit(10).dataset.uri
# => #<URI::HTTP http://localhost:8000/api/v1/users?start=0&size=10>
posts.by_user(1).dataset.uri
# => #<URI::HTTP http://localhost:8000/api/v1/users/1/posts>
此外,对于嵌套资源,ROM 可以自动查询这些资源,请查看下面的(过时的)示例部分以了解其工作原理。