rom-http
rom-http copied to clipboard
Document creating an adapter more thoroughly
I have the following adapter code:
require 'rom'
require 'rom-http'
module ROM
module RestfullClientAdapter
class Dataset < ROM::HTTP::Dataset
default_request_handler -> (dataset) do
puts "begin request"
end
default_response_handler -> (response, dataset) do
puts "end request"
end
def response_transformer(response)
end
end
class Gateway < ROM::HTTP::Gateway; end
class Relation < ROM::HTTP::Relation
adapter :restfull_client
end
module Commands
class Create < ROM::HTTP::Commands::Create
adapter :restfull_client
end
class Update < ROM::HTTP::Commands::Update
adapter :restfull_client
end
class Delete < ROM::HTTP::Commands::Delete
adapter :restfull_client
end
end
end
end
ROM.register_adapter(:restfull_client, ROM::RestfullClientAdapter)
and I'm getting to following exception:
KeyError: key not found: :base
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-2.0.0/lib/rom/plugins/relation/view.rb:35:in `fetch'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-2.0.0/lib/rom/plugins/relation/view.rb:35:in `attributes'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-repository-0.3.1/lib/rom/repository/relation_proxy.rb:212:in `method_missing'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-repository-0.3.1/lib/rom/repository/relation_proxy.rb:132:in `to_ast'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-repository-0.3.1/lib/rom/repository.rb:203:in `compile_command'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-repository-0.3.1/lib/rom/repository.rb:138:in `block in command'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/concurrent-ruby-1.0.2/lib/concurrent/map.rb:133:in `block in fetch_or_store'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/concurrent-ruby-1.0.2/lib/concurrent/map.rb:122:in `fetch'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/concurrent-ruby-1.0.2/lib/concurrent/map.rb:132:in `fetch_or_store'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-repository-0.3.1/lib/rom/repository.rb:137:in `command'
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-repository-0.3.1/lib/rom/repository/class_interface.rb:116:in `block in define_command_method'
./spec/rom_restful_client_adapter_spec.rb:15:in `block (2 levels) in <top (required)>'
-e:1:in `load'
-e:1:in `<main>'
After digging a bit it seems I need to set the option base to be an instance but I'm not sure of which class. So I did:
class Relation < ROM::HTTP::Relation
adapter :restfull_client
option :base, self
end
and now I get:
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-support-2.0.0/lib/rom/support/options.rb:49:in `initialize': undefined method `fetch' for ROM::RestfullClientAdapter::Relation:Class (NoMethodError)
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-support-2.0.0/lib/rom/support/options.rb:164:in `new'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-support-2.0.0/lib/rom/support/options.rb:164:in `option'
from /Volumes/fiverr_dev/restfull-client/lib/rom_adapter.rb:25:in `<class:Relation>'
from /Volumes/fiverr_dev/restfull-client/lib/rom_adapter.rb:22:in `<module:RestfullClientAdapter>'
from /Volumes/fiverr_dev/restfull-client/lib/rom_adapter.rb:5:in `<module:ROM>'
from /Volumes/fiverr_dev/restfull-client/lib/rom_adapter.rb:4:in `<top (required)>'
from /Volumes/fiverr_dev/restfull-client/spec/support/models.rb:2:in `require'
from /Volumes/fiverr_dev/restfull-client/spec/support/models.rb:2:in `<top (required)>'
from /Volumes/fiverr_dev/restfull-client/spec/spec_helper.rb:6:in `load'
from /Volumes/fiverr_dev/restfull-client/spec/spec_helper.rb:6:in `block in <top (required)>'
from /Volumes/fiverr_dev/restfull-client/spec/spec_helper.rb:6:in `each'
from /Volumes/fiverr_dev/restfull-client/spec/spec_helper.rb:6:in `<top (required)>'
from /Users/omer.katz/.rvm/rubies/ruby-2.2.2/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /Users/omer.katz/.rvm/rubies/ruby-2.2.2/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration.rb:1394:in `block in requires='
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration.rb:1394:in `each'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration.rb:1394:in `requires='
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration_options.rb:112:in `block in process_options_into'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration_options.rb:111:in `each'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration_options.rb:111:in `process_options_into'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration_options.rb:21:in `configure'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/runner.rb:99:in `setup'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/runner.rb:86:in `run'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/invocations.rb:23:in `call'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/runner.rb:69:in `run'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/runner.rb:45:in `invoke'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/exe/rspec:4:in `<top (required)>'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/bin/rspec:23:in `load'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/bin/rspec:23:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
After adding fetch to the Relation class I get:
/Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-2.0.0/lib/rom/relation/class_interface.rb:129:in `rescue in []': Failed to find relation class for coercer adapter. Make sure ROM setup was started and the adapter identifier is correct. (ROM::AdapterNotPresentError)
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-2.0.0/lib/rom/relation/class_interface.rb:127:in `[]'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-support-2.0.0/lib/rom/support/options.rb:51:in `initialize'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-support-2.0.0/lib/rom/support/options.rb:164:in `new'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rom-support-2.0.0/lib/rom/support/options.rb:164:in `option'
from /Volumes/fiverr_dev/restfull-client/lib/rom_adapter.rb:29:in `<class:Relation>'
from /Volumes/fiverr_dev/restfull-client/lib/rom_adapter.rb:22:in `<module:RestfullClientAdapter>'
from /Volumes/fiverr_dev/restfull-client/lib/rom_adapter.rb:5:in `<module:ROM>'
from /Volumes/fiverr_dev/restfull-client/lib/rom_adapter.rb:4:in `<top (required)>'
from /Volumes/fiverr_dev/restfull-client/spec/support/models.rb:2:in `require'
from /Volumes/fiverr_dev/restfull-client/spec/support/models.rb:2:in `<top (required)>'
from /Volumes/fiverr_dev/restfull-client/spec/spec_helper.rb:6:in `load'
from /Volumes/fiverr_dev/restfull-client/spec/spec_helper.rb:6:in `block in <top (required)>'
from /Volumes/fiverr_dev/restfull-client/spec/spec_helper.rb:6:in `each'
from /Volumes/fiverr_dev/restfull-client/spec/spec_helper.rb:6:in `<top (required)>'
from /Users/omer.katz/.rvm/rubies/ruby-2.2.2/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /Users/omer.katz/.rvm/rubies/ruby-2.2.2/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration.rb:1394:in `block in requires='
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration.rb:1394:in `each'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration.rb:1394:in `requires='
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration_options.rb:112:in `block in process_options_into'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration_options.rb:111:in `each'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration_options.rb:111:in `process_options_into'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/configuration_options.rb:21:in `configure'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/runner.rb:99:in `setup'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/runner.rb:86:in `run'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/invocations.rb:23:in `call'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/runner.rb:69:in `run'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/lib/rspec/core/runner.rb:45:in `invoke'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/gems/rspec-core-3.5.2/exe/rspec:4:in `<top (required)>'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/bin/rspec:23:in `load'
from /Users/omer.katz/.rvm/gems/ruby-2.2.2@restfull_client/bin/rspec:23:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
It's really not clear what I should be doing. Can you guys please help me and also document the process?
Sorry, just looked into this and it seems that the dataset no longer infers register_as, you don't need a base view unless you're using rom-repository, try updating your relation to use register_as:
class Users < ROM::Relation[:my_adapter]
dataset :users
register_as :users
def by_id(id)
with_path(id.to_s)
end
end
Full example:
require 'json'
require 'uri'
require 'net/http'
gemfile(true) do
gem 'rom'
gem 'rom-http'
end
module ROM
module MyAdapter
class Dataset < ROM::HTTP::Dataset
default_request_handler ->(dataset) do
uri = URI(dataset.uri)
uri.path = "/#{dataset.name}/#{dataset.path}"
uri.query = URI.encode_www_form(dataset.params)
http = Net::HTTP.new(uri.host, uri.port)
request_klass = Net::HTTP.const_get(ROM::Inflector.classify(dataset.request_method))
request = request_klass.new(uri.request_uri)
dataset.headers.each_with_object(request) do |(header, value), request|
request[header.to_s] = value
end
response = http.request(request)
end
default_response_handler ->(response, dataset) do
Array([JSON.parse(response.body)]).flatten
end
end
class Gateway < ROM::HTTP::Gateway; end
class Relation < ROM::HTTP::Relation
adapter :my_adapter
end
module Commands
class Create < ROM::HTTP::Commands::Create
adapter :my_adapter
end
class Update < ROM::HTTP::Commands::Update
adapter :my_adapter
end
class Delete < ROM::HTTP::Commands::Delete
adapter :my_adapter
end
end
end
end
ROM.register_adapter(:my_adapter, ROM::MyAdapter)
configuration = ROM::Configuration.new(:my_adapter, {
uri: 'http://jsonplaceholder.typicode.com',
headers: {
Accept: 'application/json'
}
})
class Users < ROM::Relation[:my_adapter]
dataset :users
register_as :users
def by_id(id)
with_path(id.to_s)
end
end
configuration.register_relation(Users)
container = ROM.container(configuration)
container.relation(:users).by_id(1).to_a
I am using rom-repository.
Here's a working example with rom-repository:
require 'json'
require 'uri'
require 'net/http'
gemfile(true) do
gem 'rom'
gem 'rom-http'
gem 'rom-repository'
end
module ROM
module MyAdapter
class Dataset < ROM::HTTP::Dataset
default_request_handler ->(dataset) do
uri = URI(dataset.uri)
uri.path = "/#{dataset.name}/#{dataset.path}"
uri.query = URI.encode_www_form(dataset.params)
http = Net::HTTP.new(uri.host, uri.port)
request_klass = Net::HTTP.const_get(ROM::Inflector.classify(dataset.request_method))
request = request_klass.new(uri.request_uri)
dataset.headers.each_with_object(request) do |(header, value), request|
request[header.to_s] = value
end
response = http.request(request)
end
default_response_handler ->(response, dataset) do
Array([JSON.parse(response.body, symbolize_names: true)]).flatten
end
end
class Gateway < ROM::HTTP::Gateway; end
class Relation < ROM::HTTP::Relation
adapter :my_adapter
end
module Commands
class Create < ROM::HTTP::Commands::Create
adapter :my_adapter
end
class Update < ROM::HTTP::Commands::Update
adapter :my_adapter
end
class Delete < ROM::HTTP::Commands::Delete
adapter :my_adapter
end
end
end
end
ROM.register_adapter(:my_adapter, ROM::MyAdapter)
configuration = ROM::Configuration.new(:my_adapter, {
uri: 'http://jsonplaceholder.typicode.com',
headers: {
Accept: 'application/json'
}
})
class Users < ROM::Relation[:my_adapter]
dataset :users
register_as :users
schema do
attribute :id, ROM::Types::Int
attribute :name, ROM::Types::String
attribute :username, ROM::Types::String
attribute :email, ROM::Types::String
attribute :phone, ROM::Types::String
attribute :website, ROM::Types::String
end
view(:base, %i(id name username email phone website)) do
self
end
def by_id(id)
with_path(id.to_s)
end
end
configuration.register_relation(Users)
container = ROM.container(configuration)
class UserRepository < ROM::Repository[:users]
def find(id)
users.by_id(id).one!
end
end
user_repo = UserRepository.new(container)
user_repo.find(1)
# => #<ROM::Struct[User] id=1 name="Leanne Graham" username="Bret" email="[email protected]" phone="1-770-736-8031 x56442" website="hildegard.org">
Closing due to inactivity
Why are you closing this issue? Has the documentation been updated and extended?
Fair point