Skip to content

Commit

Permalink
Merge pull request #80 from koenpunt/faraday-options
Browse files Browse the repository at this point in the history
add faraday connection options without breaking api
  • Loading branch information
dblock committed Dec 2, 2014
2 parents 39b6c5f + a9ee50c commit 9f90885
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 64 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

* Your contribution here.

### 0.7.0-pre (December 1, 2014)
### 0.7.0 (December 2, 2014)

This version introduces several backwards incompatible changes. See [UPGRADING](UPGRADING.md) for details.

* [#80](https://github.com/codegram/hyperclient/pull/80): Faraday options can be passed to the connection on initialization - [@koenpunt](https://github.com/koenpunt).
* [#81](https://github.com/codegram/hyperclient/pull/81): The default Content-Type is now `application/hal+json` - [@koenpunt](https://github.com/koenpunt).

### 0.6.1 (October 17, 2014)
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ gem 'redcarpet'
gem 'yard', '~> 0.8'
gem 'yard-tomdoc'
gem 'simplecov', require: false
gem 'rubocop', '~> 0.26.0', require: false
gem 'rubocop', '~> 0.27.0', require: false
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Hyperclient

[![Build Status](https://secure.travis-ci.org/codegram/hyperclient.png)](http://travis-ci.org/codegram/hyperclient)
[![Dependency Status](https://gemnasium.com/codegram/hyperclient.png)](http://gemnasium.com/codegram/hyperclient)
[![Code Climate](https://codeclimate.com/github/codegram/hyperclient.png)](https://codeclimate.com/github/codegram/hyperclient)
[![Build Status](https://secure.travis-ci.org/codegram/hyperclient.svg)](http://travis-ci.org/codegram/hyperclient)
[![Dependency Status](https://gemnasium.com/codegram/hyperclient.svg)](http://gemnasium.com/codegram/hyperclient)
[![Code Climate](https://codeclimate.com/github/codegram/hyperclient.svg)](https://codeclimate.com/github/codegram/hyperclient)

Hyperclient is a Hypermedia API client written in Ruby. It fully supports [JSON HAL](http://stateless.co/hal_specification.html).

Expand Down Expand Up @@ -38,6 +38,24 @@ api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api') do |client|
end
```

You can pass options to the Faraday connection block in the `connection` block:

```ruby
api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api') do |client|
client.connection(ssl: { verify: false }) do |conn|
conn.use Faraday::Request::OAuth
end
end
```

Or when using the default connection configuration you can use `faraday_options`:

```ruby
api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api') do |client|
client.faraday_options = { ssl: { verify: false } }
end
```

You can build a new Faraday connection block without inheriting default middleware by specifying `default: false` in the `connection` block.

```ruby
Expand Down
36 changes: 26 additions & 10 deletions lib/hyperclient/entry_point.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def message
# client = Hyperclient::EntryPoint.new('http://my.api.org')
#
# client = Hyperclient::EntryPoint.new('http://my.api.org') do |entry_point|
# entry_point.connection(default: true) do |conn|
# entry_point.connection do |conn|
# conn.use Faraday::Request::OAuth
# end
# entry_point.headers['Access-Token'] = 'token'
Expand All @@ -48,22 +48,31 @@ def initialize(url, &_block)
# default - Set to true to reuse default Faraday connection options.
#
# Returns a Faraday::Connection.
def connection(options = { default: true }, &block)
def connection(options = {}, &block)
@faraday_options ||= options.dup
if block_given?
fail ConnectionAlreadyInitializedError if @connection
if options[:default]
if @faraday_options.delete(:default) == false
@faraday_block = block
else
@faraday_block = lambda do |conn|
default_faraday_block.call conn
block.call conn
end
else
@faraday_block = block
end
else
@connection ||= Faraday.new(_url, { headers: headers }, &faraday_block)
@connection ||= Faraday.new(_url, faraday_options, &faraday_block)
end
end

# Public: Headers included with every API request.
#
# Returns a Hash.
def headers
return @connection.headers if @connection
@headers ||= default_headers
end

# Public: Set headers.
#
# value - A Hash containing headers to include with every API request.
Expand All @@ -72,12 +81,19 @@ def headers=(value)
@headers = value
end

# Public: Headers included with every API request.
# Public: Options passed to Faraday
#
# Returns a Hash.
def headers
return @connection.headers if @connection
@headers ||= default_headers
def faraday_options
(@faraday_options ||= {}).merge(headers: headers)
end

# Public: Set Faraday connection options.
#
# value - A Hash containing options to pass to Faraday
def faraday_options=(value)
fail ConnectionAlreadyInitializedError if @connection
@faraday_options = value
end

# Public: Faraday block used with every API request.
Expand Down
146 changes: 97 additions & 49 deletions test/hyperclient/entry_point_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,74 +57,122 @@ module Hyperclient
end
end
end
end

describe 'custom' do
let(:entry_point) do
EntryPoint.new 'http://my.api.org' do |entry_point|
entry_point.connection(default: false) do |conn|
conn.request :json
conn.response :json, content_type: /\bjson$/
conn.adapter :net_http
describe 'faraday_options' do
let(:entry_point) do
EntryPoint.new 'http://my.api.org' do |entry_point|
entry_point.faraday_options = { proxy: 'http://my.proxy:8080' }
end
end

describe 'connection' do
it 'creates a Faraday connection with the entry point url' do
entry_point.connection.url_prefix.to_s.must_equal 'http://my.api.org/'
end

it 'creates a Faraday connection with the default headers' do
entry_point.headers['Content-Type'].must_equal 'application/hal+json'
entry_point.headers['Accept'].must_equal 'application/hal+json,application/json'
end

entry_point.headers = {
'Content-Type' => 'application/foobar',
'Accept' => 'application/foobar'
}
it 'creates a Faraday connection with options' do
entry_point.connection.proxy.must_be_kind_of Faraday::ProxyOptions
entry_point.connection.proxy.uri.to_s.must_equal 'http://my.proxy:8080'
end
end
end

describe 'connection' do
it 'creates a Faraday connection with the entry point url' do
entry_point.connection.url_prefix.to_s.must_equal 'http://my.api.org/'
describe 'options' do
let(:entry_point) do
EntryPoint.new 'http://my.api.org' do |entry_point|
entry_point.connection(proxy: 'http://my.proxy:8080')
end
end

it 'creates a Faraday connection with non-default headers' do
entry_point.headers['Content-Type'].must_equal 'application/foobar'
entry_point.headers['Accept'].must_equal 'application/foobar'
end
describe 'connection' do
it 'creates a Faraday connection with the entry point url' do
entry_point.connection.url_prefix.to_s.must_equal 'http://my.api.org/'
end

it 'creates a Faraday connection with the default block' do
handlers = entry_point.connection.builder.handlers
handlers.wont_include Faraday::Response::RaiseError
handlers.wont_include FaradayMiddleware::FollowRedirects
handlers.must_include FaradayMiddleware::EncodeJson
handlers.must_include FaradayMiddleware::ParseJson
handlers.must_include Faraday::Adapter::NetHttp
it 'creates a Faraday connection with the default headers' do
entry_point.headers['Content-Type'].must_equal 'application/hal+json'
entry_point.headers['Accept'].must_equal 'application/hal+json,application/json'
end

it 'creates a Faraday connection with options' do
entry_point.connection.proxy.must_be_kind_of Faraday::ProxyOptions
entry_point.connection.proxy.uri.to_s.must_equal 'http://my.proxy:8080'
end
end
end
end

describe 'inherited' do
let(:entry_point) do
EntryPoint.new 'http://my.api.org' do |entry_point|
entry_point.connection(default: true) do |conn|
conn.use Faraday::Request::OAuth
describe 'custom' do
let(:entry_point) do
EntryPoint.new 'http://my.api.org' do |entry_point|
entry_point.connection(default: false) do |conn|
conn.request :json
conn.response :json, content_type: /\bjson$/
conn.adapter :net_http
end

entry_point.headers = {
'Content-Type' => 'application/foobar',
'Accept' => 'application/foobar'
}
end
entry_point.headers['Access-Token'] = 'token'
end
end

describe 'connection' do
it 'creates a Faraday connection with the default and additional headers' do
entry_point.headers['Content-Type'].must_equal 'application/hal+json'
entry_point.headers['Accept'].must_equal 'application/hal+json,application/json'
entry_point.headers['Access-Token'].must_equal 'token'
describe 'connection' do
it 'creates a Faraday connection with the entry point url' do
entry_point.connection.url_prefix.to_s.must_equal 'http://my.api.org/'
end

it 'creates a Faraday connection with non-default headers' do
entry_point.headers['Content-Type'].must_equal 'application/foobar'
entry_point.headers['Accept'].must_equal 'application/foobar'
end

it 'creates a Faraday connection with the default block' do
handlers = entry_point.connection.builder.handlers
handlers.wont_include Faraday::Response::RaiseError
handlers.wont_include FaradayMiddleware::FollowRedirects
handlers.must_include FaradayMiddleware::EncodeJson
handlers.must_include FaradayMiddleware::ParseJson
handlers.must_include Faraday::Adapter::NetHttp
end
end
end

it 'creates a Faraday connection with the entry point url' do
entry_point.connection.url_prefix.to_s.must_equal 'http://my.api.org/'
describe 'inherited' do
let(:entry_point) do
EntryPoint.new 'http://my.api.org' do |entry_point|
entry_point.connection do |conn|
conn.use Faraday::Request::OAuth
end
entry_point.headers['Access-Token'] = 'token'
end
end

it 'creates a Faraday connection with the default block plus any additional handlers' do
handlers = entry_point.connection.builder.handlers
handlers.must_include Faraday::Request::OAuth
handlers.must_include Faraday::Response::RaiseError
handlers.must_include FaradayMiddleware::FollowRedirects
handlers.must_include FaradayMiddleware::EncodeHalJson
handlers.must_include FaradayMiddleware::ParseHalJson
handlers.must_include Faraday::Adapter::NetHttp
describe 'connection' do
it 'creates a Faraday connection with the default and additional headers' do
entry_point.headers['Content-Type'].must_equal 'application/hal+json'
entry_point.headers['Accept'].must_equal 'application/hal+json,application/json'
entry_point.headers['Access-Token'].must_equal 'token'
end

it 'creates a Faraday connection with the entry point url' do
entry_point.connection.url_prefix.to_s.must_equal 'http://my.api.org/'
end

it 'creates a Faraday connection with the default block plus any additional handlers' do
handlers = entry_point.connection.builder.handlers
handlers.must_include Faraday::Request::OAuth
handlers.must_include Faraday::Response::RaiseError
handlers.must_include FaradayMiddleware::FollowRedirects
handlers.must_include FaradayMiddleware::EncodeHalJson
handlers.must_include FaradayMiddleware::ParseHalJson
handlers.must_include Faraday::Adapter::NetHttp
end
end
end
end
Expand Down

0 comments on commit 9f90885

Please sign in to comment.