-
-
Save AMHOL/f76b953893b0431e4cc1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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