# 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