Настройка отношения rom-http для REST CRUD
Я пытаюсь установить отношение rom-http для базового REST CRUD, но нахожу документацию довольно скудной для новичка и слишком сложной при копании. Пока я пробовал вот что:
rom = ROM.container(:http, uri: 'http://localhost:8000', handlers: :json) do |conf|
conf.relation(:users) do
schema(:users) do
end
end
end
Это запрашивает URI http://localhost:8000/users, но как мне настроить префиксы, параметры и связанные ресурсы?
Я бы хотел использовать URI, например http: // localhost: 8000 / users / 1 / posts? Start = 0 & size = 10, где мы имеем
- глобальный префикс (
api
) - префикс версии (
v1
, может быть частью глобального префикса) - родительский ресурс (
users/1
) - дочерний ресурс (
posts
) - параметры запроса (бонусные баллы, если они могут быть связаны как
.offset(0).limit(10)
)
Возможно ли это с текущей реализацией? В документации можно использовать более глубокий пример, не заставляя новичков копаться в архитектуре - что, без сомнения, блестяще, но сложно для кого-то, исходя из простоты использования (и ловушек) ActiveRecord.:-)
0 ответов
Извините, что никто еще не ответил на это, текущий встроенный обработчик 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 может запрашивать их автоматически, проверьте разделы (устаревшие) примеров ниже, чтобы увидеть, как это работает.
- https://github.com/rom-rb/rom-http/blob/57ca3703bf82bc9d7b2c3304752947de2c6d6dea/examples/repository_with_combine.rb
- https://github.com/rom-rb/rom-http/blob/57ca3703bf82bc9d7b2c3304752947de2c6d6dea/examples/repository_with_combine.rb
- https://github.com/rom-rb/rom-http/blob/57ca3703bf82bc9d7b2c3304752947de2c6d6dea/examples/repository_with_combine.rb