HTTP support for ROM.
rom-http is an adapter that integrates the http HTTP client library with the rom data library, allowing you to consume, transform, and even persist to external APIs.
It's very much a work in progress. Use judiciously, and please report issues and feature requests!
To install in your project:
$ echo "gem 'rom-http'" >> Gemfile
$ bundle installTo install globally:
$ gem install rom-httpProvide the adapter with a root http url to get started:
ROM.setup :http, 'http://jsonplaceholder.typicode.com'You can also pass in a pre-configured HTTP client:
client = HTTP[accept: "application/json"].basic_auth(:user => "user", :pass => "pass")
ROM.setup :http, 'http://jsonplaceholder.typicode.com', client
# The repository will use those headers with the provided basic auth settings.Define relations in the usual way:
# Calls out to http://jsonplaceholder.typicode.com/posts
class Posts < ROM::Relation[:http]
# Calls out to http://jsonplaceholder.typicode.com/posts/:id
def by_id(id)
get id
end
end
rom = ROM.finalize
rom.relation(:posts).to_a
=begin
[
{
"userId"=>1,
"id"=>1,
"title"=>"sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body"=>"quia et suscipit\nsuscipit recusandae consequuntur expedita et cum..."
{
"userId"=>1,
"id"=>2,
"title"=>"qui est esse",
"body"=>"est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores..."
}
#...
]
=end
rom.relation(:posts).by_id(1)
=begin
[
{
"userId"=>1,
"id"=>1,
"title"=>"sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body"=>"quia et suscipit\nsuscipit recusandae consequuntur expedita et cum..."
}
]
=endThe underlying dataset available to you in your relations leverages a simple wrapper DSL around http that allows you to compose requests:
class Posts < ROM::Relation[:http]
def example_usage(*args, opts = {}, &block)
# Generally, you won't need to access the raw `dataset` object.
# You definitely don't want to `.call` it or enumerate it inside of the relationship–
# let ROM do that for you. However, for rigor:
# By default, this is a request to GET from root_url/relation_name:
dataset
# To actually perform the HTTP call:
dataset.call
# To perform the call, parse the body, and enumerate over the results:
dataset.each do |post|
puts post
end
# The rest of the DSL delegates to the dataset object, allowing you to modify the request you send:
# HTTP verb methods allow you to modify the verb and append to the path in the same go:
# Append 'foobar' to the request: GET from root_url/relation_name/foobar
get 'foobar'
# Append 'foobar' to the request, use query string parameters: GET from root_url/relation_name/foobar?fizz=buzz
get 'foobar', params: { fizz: :buzz }
# Make a request to POST to root_url/relation_name with an encoded form
post form: { fizz: :buzz }
# Make a request to POST to root_url/relation_name with a raw body
post body: "foo=42&bar=baz"
# Make a request to POST to root_url/relation_name with a JSON body
post json: { fizz: :buzz }
# Make a request to PUT to root_url/relation_name/1 with a JSON body
put 1, json: { fizz: :buzz }
# Verbs can be chained to re-write the verb, allowing you to reuse requests as different types:
# Make a request to PUT to root_url/relation_name/1 with an encoded body
post(form: {fizz: :buzz}).put(1)
# Using the params/form/body syntax above will override previously set values:
# Use query string parameters: GET from root_url/relation_name?fizz=buzz
get(params: { foo: :bar }).get(params: { fizz: :buzz })
# For finer control, you can use the params/form/body DSL methods:
# Use query string parameters: GET from root_url/relation_name?foo=baz&fizz=buzz
get(params: { foo: :bar }).params(fizz: :buzz) do |old_params|
old_params.merge(foo: :bar)
end
# Since the default dataset is a get request to the relation_name, and the DSL delegates to the dataset,
# it's trivial to make composable relation methods that simply modify the querystring parameters with a one-liner:
params page: opts.fetch(:page, 1), per_page: opts.fetch(:per_page, 10)
params order: opts.fetch(:order, :asc), column: opts.fetch(:column)
# Finally, the rest of the `http` library DSL is available to modify other parts of the request:
get('foobar').headers("Cookie" => "9wq3w").basic_auth(:user => "user", :pass => "pass").accept(:json)
end
endMost frequently in your relations, you'll just be making simple get requests to an endpoint, and using commands to do more involved things.
- Fork it ( https://github.com/[my-github-username]/rom-http/fork )
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request