diff --git a/CHANGELOG.md b/CHANGELOG.md index b44abf7..0420365 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/Gemfile b/Gemfile index e9ac5cd..2080d93 100644 --- a/Gemfile +++ b/Gemfile @@ -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 diff --git a/README.md b/README.md index 6d6ca10..c3bbcdb 100644 --- a/README.md +++ b/README.md @@ -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). @@ -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 diff --git a/lib/hyperclient/entry_point.rb b/lib/hyperclient/entry_point.rb index 66282f2..6a1fd8b 100644 --- a/lib/hyperclient/entry_point.rb +++ b/lib/hyperclient/entry_point.rb @@ -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' @@ -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. @@ -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. diff --git a/test/hyperclient/entry_point_test.rb b/test/hyperclient/entry_point_test.rb index 4313b4c..08eda56 100644 --- a/test/hyperclient/entry_point_test.rb +++ b/test/hyperclient/entry_point_test.rb @@ -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