RemoteResource
RemoteResource is a gem to use resources with REST services.
Goal of RemoteResource
To replace ActiveResource
by providing a dynamic and customizable API interface for REST services.
Installation
Add this line to your application's Gemfile:
# Use this to fetch the gem from Gitlab
gem 'remote_resource', git: '[email protected]:jvanderpas/remote_resource.git'
# Use this to fetch the gem from RubyGems.org
gem 'ddy_remote_resource', require: 'remote_resource'
Usage
Simply include the RemoteResource::Base
module in the class you want to enable for the REST services.
class ContactPerson
include RemoteResource::Base
self.site = "https://www.myapp.com"
self.version = '/v2'
end
Options
You can set a few options for the RemoteResource
enabled class.
Base URL options (base_url
)
The base_url
is constructed from the .site
, .version
, .path_prefix
, .path_postfix
, .collection
, .collection_prefix
, and .collection_name
options. The .collection_name
is automatically constructed from the relative class name.
We will use the ContactPerson
class for these examples, with the .collection_name
of 'contact_person'
:
.site
: This sets the URL which should be used to construct thebase_url
.- Example:
.site = "https://www.myapp.com"
base_url
:https://www.myapp.com/contact_person
- Example:
.version
: This sets the API version for the path, after the.site
and before the.path_prefix
that is used to construct thebase_url
.- Example:
.version = "/api/v2"
base_url
:https://www.myapp.com/api/v2/contact_person
- Example:
.path_prefix
: This sets the prefix for the path, after the.version
and before the.collection_name
that is used to construct thebase_url
.- Example:
.path_prefix = "/registration"
base_url
:https://www.myapp.com/registration/contact_person
- Example:
.path_postfix
: This sets the postfix for the path, after the.collection_name
that is used to construct thebase_url
.- Example:
.path_postfix = "/new"
base_url
:https://www.myapp.com/contact_person/new
- Example:
.collection
: This toggles the pluralization of thecollection_name
that is used to construct thebase_url
.- Default:
false
- Example:
.collection = true
base_url
:https://www.myapp.com/contact_persons
- Default:
.collection_prefix
: This sets the prefix for the collection, beforecollection_name
that is used to construct thebase_url
. The prefix variable has to be set via connection_options' keycollection_options
.- Default: ``
- Example:
.collection_prefix = "/companies/:company_id"
and connection_optionscollection_options: { company_id: 2 }
base_url
:https://www.myapp.com/companies/2/contact_persons
.collection_name
: This sets thecollection_name
that is used to construct thebase_url
.- Example:
.collection_name = "company"
base_url
:https://www.myapp.com/company
- Example:
override
To override the base_url
completely, you can use the base_url
option. This option should be passed into the connection_options
hash when making a request:
base_url
: This sets thebase_url
. note: this does not override the.content_type
option- Example:
{ base_url: "https://api.foo.com/v1" }
base_url
:https://api.foo.com/v1
- Example:
Request options
Apart from the options which manipulate the base_url
, there are some more:
.extra_headers
: This sets the extra headers which are merged with the.default_headers
and should be used for the request. note: you can't set the.default_headers
- Default:
.default_headers
:{ "Content-Type" => "application/json" }
- Example:
.extra_headers = { "X-Locale" => "en" }
.headers
:{ "Content-Type" => "application/json", "X-Locale" => "en" }
- Default:
.content_type
: This sets the content-type which should be used for the request URL. note: this is appended to thebase_url
- Default:
".json"
base_url
:https://www.myapp.com/contact_person
- Example:
.content-type = ".json"
- Request URL:
https://www.myapp.com/contact_person.json
- Default:
Body and params options
Last but not least, you can pack the request body or params in a root_element
:
.root_element
: This sets theroot_element
in which the request body or params should be 'packed' for the request.- Params:
{ email_address: "[email protected]", phone_number: "0031701234567" }
- Example:
.root_element = :contact_person
- Packed params:
{ "contact_person" => { email_address: "[email protected]", phone_number: "0031701234567" } }
- Params:
Querying
Finder methods
You can use the .find
, .find_by
and .all
class methods:
# use the `id` as argument
ContactPerson.find(12)
# use a conditions `Hash` as argument
ContactPerson.find_by(username: 'foobar')
# just the whole collection
ContactPerson.all
To override the given options
, you can pass in a connection_options
hash:
connection_options: { root_element: :contact_person, headers: { "X-Locale" => "nl" } }
# use the `id` as argument
ContactPerson.find(12, connection_options)
# use a conditions `Hash` as argument
ContactPerson.find_by((username: 'foobar'), connection_options)
Persistence methods
You can use the .create
class method and the #save
instance method:
# .create
ContactPerson.create(username: 'aapmies', first_name: 'Mies')
# #save
contact_person = ContactPerson.new(id: 12)
contact_person.username = 'aapmies'
contact_person.save
To override the given options
, you can pass in a connection_options
hash:
connection_options: { root_element: :contact_person, headers: { "X-Locale" => "nl" } }
contact_person = ContactPerson.new(id: 12)
contact_person.username = 'aapmies'
contact_person.save(connection_options)
REST methods
You can use the .get
, .put
, .patch
and .post
class methods and the `
get,
#put,
#patchand
#post` instance methods.
With a connection_options
block
You can make your requests in a connection_options
block. All the requests in the block will use the passed in connection_options
.
ContactPerson.with_connection_options(headers: { "X-Locale" => "en" }) do
ContactPerson.find_by(username: 'foobar')
ContactPerson.find_by(username: 'aapmies', (content-type: '.xml'))
ContactPerson.find_by((username: 'viking'), (headers: { "X-Locale" => "nl" }))
end
This will result in two request which use the { headers: { "X-Locale" => "en" } }
as connection_options
, one which will use the { headers: { "X-Locale" => "nl" } }
as connection_options
. And one that will append .xml
to the request URL.
Responses
The response body of the request will be 'unpacked' from the root_element
if necessary and parsed. The resulting Hash
will be used to assign the attributes of the resource.
However if you want to access the response of the request, you can use the #_response
method. This returns a RemoteResource::Response
object with the #response_body
and #response_code
methods.
contact_person = ContactPerson.find_by((username: 'foobar'), connection_options)
contact_person._response #=> RemoteResource::Response
contact_person._response.response_code #=> 200
contact_person._response.response_body #=> '{"username":"foobar", "name":"Foo", "surname":"Bar"}'