Skip to content

Instantly share code, notes, and snippets.

@AMHOL AMHOL/http_repo_model_mapping.rb Secret
Last active May 16, 2016

Embed
What would you like to do?
# gem install anima rom rom-http rom-repository inflecto
require 'anima'
require 'rom'
require 'rom/memory'
require 'rom-http'
require 'rom-repository'
require 'json'
require 'uri'
require 'inflecto'
require 'net/http'
module Transformer
extend Transproc::Registry
import :map_array, from: Transproc::ArrayTransformations
import :hash_recursion, from: Transproc::Recursion
import :map_keys, from: Transproc::HashTransformations
import :underscore, from: Inflecto
import :to_symbol, from: Transproc::Coercions
module_function
def transform_tuples(tuples)
t(:map_array, t(:hash_recursion, t(:map_keys, t(:underscore) >> t(:to_symbol))))[tuples]
end
end
class RequestHandler
def call(dataset)
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), req|
req[header.to_s] = value
end
http.request(request)
end
end
class ResponseHandler
def call(response, dataset)
Transformer[:transform_tuples][Array([JSON.parse(response.body)]).flatten]
end
end
rom = ROM::Environment.new
rom.setup(:http, {
uri: 'http://jsonplaceholder.typicode.com',
headers: {
Accept: 'application/json'
},
request_handler: RequestHandler.new,
response_handler: ResponseHandler.new
})
class Users < ROM::Relation[:http]
dataset :users
use :view
use :key_inference
def primary_key
:id
end
view(:base, [:id, :name, :username, :email, :address, :phone, :website, :company]) do
self
end
def by_id(id)
with_path(id.to_s)
end
end
class User
include Anima.new(:id, :name, :username, :email, :address, :phone, :website, :company)
def initialize(attributes = {})
super(attributes.to_hash)
end
end
class UserMapper < ROM::Mapper
relation :users
register_as :entity
model User
end
rom.register_relation(Users)
rom.register_mapper(UserMapper)
container = rom.finalize.env
class UserRepository < ROM::Repository::Base
relations :users
def by_id(id)
users.by_id(id)
end
end
user_repo = UserRepository.new(container)
user_repo.by_id(1).as(:entity).first
# => #<User id=1 name="Leanne Graham" username="Bret" email="Sincere@april.biz" address={:street=>"Kulas Light", :suite=>"Apt. 556", :city=>"Gwenborough", :zipcode=>"92998-3874", :geo=>{:lat=>"-37.3159", :lng=>"81.1496"}} phone="1-770-736-8031 x56442" website="hildegard.org" company={:name=>"Romaguera-Crona", :catch_phrase=>"Multi-layered client-server neural-net", :bs=>"harness real-time e-markets"}>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.