Skip to content
Abstract HTTP adapter for ROM
Branch: master
Clone or download
Latest commit 536529a Mar 31, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples
lib Doc fix Mar 31, 2018
rakelib Initial commit Jun 25, 2015
spec Add Test namespace with cleaning to specs Mar 31, 2018
.gitignore Initial commit Jun 25, 2015
.rspec
.rubocop.yml
.rubocop_todo.yml Rubocop Sep 16, 2015
.travis.yml
CHANGELOG.md Release update to work with ROM 4.0 Jan 11, 2018
Gemfile
LICENSE.txt Update LICENCE & README [ci skip] Aug 10, 2015
README.md Update dataset to return URI Feb 23, 2017
Rakefile Update Rakefile Aug 13, 2015
rom-http.gemspec Upgrade rom to ~> 4.0 Nov 21, 2017

README.md

rom-http Gitter chat

Gem Version Build Status Dependency Status Code Climate Documentation Status

HTTP adapter for Ruby Object Mapper

Installation

Add this line to your application's Gemfile:

gem 'rom-http'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rom-http

ROADMAP

For details please refer to issues.

License

See LICENSE file.

Synopsis

require 'inflecto'
require 'json'
require 'uri'
require 'net/http'

class RequestHandler
  def call(dataset)
    uri = dataset.uri
    http = Net::HTTP.new(uri.host, uri.port)
    request_klass = Net::HTTP.const_get(Inflecto.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
end

class ResponseHandler
  def call(response, dataset)
    if %i(post put patch).include?(dataset.request_method)
      JSON.parse(response.body, symbolize_names: true)
    else
      Array([JSON.parse(response.body, symbolize_names: true)]).flatten
    end
  end
end

class Users < ROM::Relation[:http]
  schema(:users) 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

  def by_id(id)
    with_path(id.to_s)
  end
end

configuration = ROM::Configuration.new(:http, {
  uri: 'http://jsonplaceholder.typicode.com',
  headers: {
    Accept: 'application/json'
  },
  request_handler: RequestHandler.new,
  response_handler: ResponseHandler.new
})
configuration.register_relation(Users)
container = ROM.container(configuration)

container.relation(:users).by_id(1).to_a
# => GET http://jsonplaceholder.typicode.com/users/1 [ Accept: application/json ]

Extending

require 'inflecto'
require 'json'
require 'uri'
require 'net/http'

module ROM
  module MyAdapter
    class Dataset < ROM::HTTP::Dataset
      configure do |config|
        config.default_request_handler = ->(dataset) do
          uri = dataset.uri

          http = Net::HTTP.new(uri.host, uri.port)
          request_klass = Net::HTTP.const_get(Inflecto.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

        config.default_response_handler = ->(response, dataset) do
          if %i(post put patch).include?(dataset.request_method)
            JSON.parse(response.body, symbolize_names: true)
          else
            Array([JSON.parse(response.body, symbolize_names: true)]).flatten
          end
        end
      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]
  schema(:users) 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

  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
# => GET http://jsonplaceholder.typicode.com/users/1 [ Accept: application/json ]
You can’t perform that action at this time.