saddle 0.0.53 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -13
  2. data/.github/workflows/ci.yml +55 -0
  3. data/.gitignore +1 -0
  4. data/Appraisals +39 -0
  5. data/CHANGELOG.md +3 -0
  6. data/Gemfile +2 -2
  7. data/README.md +48 -10
  8. data/bin/template/lib/saddle-client/middleware/exception_raiser.rb +1 -1
  9. data/gemfiles/activesupport_3.2.gemfile +20 -0
  10. data/gemfiles/activesupport_4.0.gemfile +20 -0
  11. data/gemfiles/activesupport_4.1.gemfile +20 -0
  12. data/gemfiles/activesupport_4.2.gemfile +20 -0
  13. data/gemfiles/activesupport_5.0.gemfile +20 -0
  14. data/gemfiles/activesupport_5.1.gemfile +20 -0
  15. data/gemfiles/activesupport_5.2.gemfile +20 -0
  16. data/gemfiles/activesupport_6.0.gemfile +20 -0
  17. data/gemfiles/activesupport_6.1.gemfile +20 -0
  18. data/gemfiles/activesupport_7.0.gemfile +20 -0
  19. data/lib/saddle/endpoint.rb +6 -9
  20. data/lib/saddle/faraday/rack_builder.rb +15 -0
  21. data/lib/saddle/faraday/request.rb +4 -0
  22. data/lib/saddle/middleware/authentication/oauth1.rb +6 -6
  23. data/lib/saddle/middleware/authentication/oauth2.rb +2 -2
  24. data/lib/saddle/middleware/extra_env.rb +2 -2
  25. data/lib/saddle/middleware/logging/rails.rb +1 -1
  26. data/lib/saddle/middleware/logging/statsd.rb +7 -7
  27. data/lib/saddle/middleware/request/encode_json.rb +1 -7
  28. data/lib/saddle/middleware/request/path_prefix.rb +2 -2
  29. data/lib/saddle/middleware/request/retry.rb +8 -4
  30. data/lib/saddle/middleware/request/url_encoded.rb +1 -1
  31. data/lib/saddle/middleware/request/user_agent.rb +1 -1
  32. data/lib/saddle/middleware/response/default_response.rb +1 -1
  33. data/lib/saddle/middleware/response/parse_json.rb +0 -6
  34. data/lib/saddle/middleware/response/raise_error.rb +2 -2
  35. data/lib/saddle/middleware/ruby_timeout.rb +2 -2
  36. data/lib/saddle/requester.rb +27 -28
  37. data/lib/saddle/version.rb +1 -1
  38. data/saddle.gemspec +6 -8
  39. data/spec/endpoint/base_endpoint_spec.rb +2 -2
  40. data/spec/middleware/instrumentation_spec.rb +1 -1
  41. data/spec/middleware/request/retry_spec.rb +1 -1
  42. data/spec/requester/get_spec.rb +1 -1
  43. metadata +37 -24
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ODQ4YmI4OGJiZDRjMjBhNmFkOWI1NGEzZWIyNDA0NWM3NGJjZTdlMQ==
5
- data.tar.gz: !binary |-
6
- NGI3MWM5MDgzZWIyYjVkM2RhYzk1YmRjMGY5YjU3MmE2N2MxNGYyMQ==
2
+ SHA256:
3
+ metadata.gz: c6cbc5f3bed08d163ba1f6bb948acb555c16b9034ff6adac036a0f1f4252f872
4
+ data.tar.gz: 6b509a1bdb969e7b54c3c6fd93d742ef3cfd7144de2e8c36014f8a5fdc32484a
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- M2JkMWY0YTljNmFmOGI3MjA0NjY0MDRkZmU0ODc4MDNlYmYzMTNmNjVkMmJl
10
- YmI4ZjBkMzhiOWJhMmFlYjg1MGE1YTJjZDg4MmY5Mjc0N2RmNDBkZjFjZmMy
11
- ZjYxZWVjYzZiZjI1MzMwYWJmMjdiYWY3NDJmODNmMDk5ZGY0M2I=
12
- data.tar.gz: !binary |-
13
- M2Q3NWU4ODRkZGRkOWI5MDY2NmFkZWY3NDViNmZmYjE2NWJlMjEyYTBhY2Qx
14
- ZGY3M2VmYzIwMmFkMjc2M2VlZTRhNTQwZjU1Yjg1MGRlNzMyMTQ0Mzg0NDRj
15
- NGViYjZjY2EwMWIwN2VkYzgzNGU0MGI2NjJiODVkNGY5M2ZjZDU=
6
+ metadata.gz: c22f775da62289da5111c42fc64373aec52b3c831b828a0b40f9fda5d354d569da0481e8d789422965cd802ea23855816c4d53224ec3507a5a8dd977f7209c0c
7
+ data.tar.gz: 392ebba3e48907a68867ba54125fdccbc26df04659fd84db2aa053823af414da24093eca48bf3b460efaf43bfcbc1792c813b25e04c6a521b221f815ef89503d
@@ -0,0 +1,55 @@
1
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
2
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
3
+
4
+ name: Ruby
5
+
6
+ on: [pull_request, push]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ ruby-version: [2.6, 2.7, '3.0', 3.1]
17
+ gemfile:
18
+ - activesupport_3.2
19
+ - activesupport_4.0
20
+ - activesupport_4.1
21
+ - activesupport_4.2
22
+ - activesupport_5.0
23
+ - activesupport_5.1
24
+ - activesupport_5.2
25
+ - activesupport_6.0
26
+ - activesupport_6.1
27
+ - activesupport_7.0
28
+ exclude:
29
+ - ruby-version: 2.6
30
+ gemfile: activesupport_7.0
31
+ - ruby-version: '3.0'
32
+ gemfile: activesupport_4.1
33
+ - ruby-version: 3.1
34
+ gemfile: activesupport_4.1
35
+ steps:
36
+ - uses: actions/checkout@v3
37
+
38
+ - name: Set up Ruby
39
+ uses: ruby/setup-ruby@v1
40
+ with:
41
+ ruby-version: ${{ matrix.ruby-version }}
42
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
43
+
44
+ - name: Generate Appraisal gemfiles
45
+ run: bundle exec appraisal generate
46
+
47
+ - name: Install dependencies
48
+ env:
49
+ BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
50
+ run: bundle install
51
+
52
+ - name: Run rspec
53
+ env:
54
+ BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
55
+ run: bundle exec rspec
data/.gitignore CHANGED
@@ -12,6 +12,7 @@
12
12
  # Gems
13
13
  *.gem
14
14
  Gemfile.lock
15
+ gemfiles/*.lock
15
16
 
16
17
  # IDEs
17
18
  .idea
data/Appraisals ADDED
@@ -0,0 +1,39 @@
1
+ appraise "activesupport_3.2" do
2
+ gem "activesupport", "~> 3.2.22"
3
+ end
4
+
5
+ appraise "activesupport_4.0" do
6
+ gem "activesupport", "~> 4.0.13"
7
+ end
8
+
9
+ appraise "activesupport_4.1" do
10
+ gem "activesupport", "~> 4.1.16"
11
+ end
12
+
13
+ appraise "activesupport_4.2" do
14
+ gem "activesupport", "~> 4.2.11"
15
+ end
16
+
17
+ appraise "activesupport_5.0" do
18
+ gem "activesupport", "~> 5.0.7"
19
+ end
20
+
21
+ appraise "activesupport_5.1" do
22
+ gem "activesupport", "~> 5.1.7"
23
+ end
24
+
25
+ appraise "activesupport_5.2" do
26
+ gem "activesupport", "~> 5.2.8"
27
+ end
28
+
29
+ appraise "activesupport_6.0" do
30
+ gem "activesupport", "~> 6.0.6"
31
+ end
32
+
33
+ appraise "activesupport_6.1" do
34
+ gem "activesupport", "~> 6.1.7"
35
+ end
36
+
37
+ appraise "activesupport_7.0" do
38
+ gem "activesupport", "~> 7.0.4"
39
+ end
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ # 0.0.54
2
+ * Work with faraday ~> 0.9.0. With these changes, Saddle no longer works with faraday < 0.9.
3
+
1
4
  # 0.0.49
2
5
  * Support `extra_env` as a client option to load more into the env pre-adapter.
3
6
 
data/Gemfile CHANGED
@@ -4,8 +4,8 @@ gemspec
4
4
 
5
5
  group :test do
6
6
  gem 'rake'
7
- gem 'rspec', '~> 2.14.1'
8
- gem 'rspec-instafail', '~> 0.2'
7
+ gem 'rspec', '~> 3.12'
8
+ gem 'rspec-instafail', '~> 1'
9
9
 
10
10
  gem 'airbrake'
11
11
  gem 'simple_oauth', '~> 0.2.0' # Optional dependency
data/README.md CHANGED
@@ -41,16 +41,16 @@ Saddle enables you to create beautifully stable and functionaly API clients, in
41
41
  [saddle-example](https://github.com/mLewisLogic/saddle-example)
42
42
 
43
43
  ### client construction
44
- 0. For the sake of cleanliness, pick a namespace that everything related to your client should live in. For this example, we'll use __SaddleExample__
45
- 1. Inherit your client class, __SaddleExample::Client__, from __Saddle::Client__
46
- 2. Create an _endpoints_ directory at the same level as your client class file
47
- 3. Create endpoint classes in the _endpoints_ directory that inherit from __Saddle::TraversalEndpoint__ and are under the __SaddleExample::Endpoints__ namespace module
48
- 1. Give these endpoints methods that call _get_ or _post_ to perform the actual request
49
- 2. Their module/class namespace determines how they are accessed in the client's call tree. For example, the get\_all() in __SaddleExample::Endpoints::Fish::Guppy__ would be accessed by:
44
+ 0. For the sake of cleanliness, pick a namespace that everything related to your client should live in. For this example, we'll use __SaddleExample__.
45
+ 1. Inherit your client class, __SaddleExample::Client__, from __Saddle::Client__.
46
+ 2. Create an _endpoints_ directory at the same level as your client class file.
47
+ 3. Create endpoint classes in the _endpoints_ directory that inherit from __Saddle::TraversalEndpoint__ and are under the __SaddleExample::Endpoints__ namespace module.
48
+ 1. Give these endpoints methods that call `get` or `post` to perform the actual request
49
+ 2. Their module/class namespace determines how they are accessed in the client's call tree. For example, the `get_all` in __SaddleExample::Endpoints::Fish::Guppy__ would be accessed by:
50
50
 
51
- client.fish.guppy.get_all()
51
+ client.fish.guppy.get_all
52
52
 
53
- 3. If you need REST style endpoints like client.fish('guppy').catch() then check out __Saddle::ResourceEndpoint__ and how it's used in [saddle-example](https://github.com/mLewisLogic/saddle-example/blob/master/lib/endpoints/kitten.rb)
53
+ 3. If you need REST style endpoints like `client.kitten.by_id('Whiskers').info` then check out __Saddle::ResourceEndpoint__ and how it's used in [saddle-example](https://github.com/mLewisLogic/saddle-example/blob/master/lib/saddle-example/endpoints/kitten.rb)
54
54
 
55
55
  4. Initialize an instance of your client. ex:
56
56
 
@@ -62,11 +62,49 @@ Saddle enables you to create beautifully stable and functionaly API clients, in
62
62
  * xml posting/parsing
63
63
 
64
64
 
65
+ ## version notes
66
+
67
+ * Saddle versions 0.2.x supports Ruby 3.x, drops support for 2.6
68
+ * Saddle versions 0.1.x are compatible with Faraday versions ~> 0.9.0
69
+ * Saddle versions 0.0.x are compatible with Faraday versions ~> 0.8.7
70
+
71
+ ## Appraisal Usage
72
+
73
+ Appraisal is a gem that allows us to test our library against different versions of dependencies in repeatable scenarios called "appraisals". For more information see
74
+ the [Appraisal repository](https://github.com/thoughtbot/appraisal)
75
+
76
+ First make sure appraisal is installed by running
77
+
78
+ ```
79
+ $ bundle install
80
+ ```
81
+
82
+ To update the Appraisal's gemfiles run
83
+
84
+ ```
85
+ $ bundle exec appraisal generate
86
+ ```
87
+
88
+ To test against a specific version of `activesupport` first install the dependencies, ideally we would want to install them by running
89
+ ```
90
+ $ bundle exec appraisal install
91
+ ```
92
+
93
+ However, this isn't posible fot the different constraints these versions have. So instead install the dependencies for the desired version we want to test against by running
94
+
95
+ ```
96
+ $ BUNDLE_GEMFILE=gemfiles/activesupport_6.0.gemfiles bundle install
97
+ ```
98
+
99
+ In this example we want to install the dependencies of `activesupport` version `6.0`. Then to run `rspec` with that constraints we run
100
+
101
+ ```
102
+ $ BUNDLE_GEMFILE=gemfiles/activesupport_6.0.gemfiles bundle exec rspec
103
+ ```
104
+
65
105
  ## Code Status
66
106
 
67
- * [![Build Status](https://travis-ci.org/mLewisLogic/saddle.png?branch=master)](https://travis-ci.org/mLewisLogic/saddle)
68
107
  * [![Code Climate](https://codeclimate.com/github/mLewisLogic/saddle.png)](https://codeclimate.com/github/mLewisLogic/saddle)
69
- * [![Dependency Status](https://gemnasium.com/mLewisLogic/saddle.png)](https://gemnasium.com/mLewisLogic/saddle)
70
108
 
71
109
 
72
110
  ## License
@@ -19,7 +19,7 @@ module <%= root_module %>
19
19
  def call(env)
20
20
  begin
21
21
  @app.call(env)
22
- rescue Faraday::Error::ClientError => e
22
+ rescue Faraday::ClientError => e
23
23
  # This is our chance to reinterpret the response into a meaningful, client-specific
24
24
  # exception that a consuming service can handle
25
25
  exception = <%= root_module %>::GenericException
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 3.2.22"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.0.13"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.1.16"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.2.11"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 5.0.7"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 5.1.7"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 5.2.8"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 6.0.6"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 6.1.7"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 3.12"
10
+ gem "rspec-instafail", "~> 1"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 7.0.4"
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec", "~> 2.14.1"
10
+ gem "rspec-instafail", "~> 0.2"
11
+ gem "airbrake"
12
+ gem "simple_oauth", "~> 0.2.0"
13
+ gem "statsd-ruby", require: ["statsd"]
14
+ end
15
+
16
+ group :development, :test do
17
+ gem "pry"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -17,18 +17,15 @@ module Saddle
17
17
  def initialize(requester, relative_path_override=nil, parent=nil)
18
18
  @requester = requester
19
19
  @parent = parent
20
- @relative_path = relative_path_override || _relative_path()
20
+ @relative_path = relative_path_override || _relative_path
21
21
  end
22
22
 
23
23
 
24
24
  # Generic request wrapper
25
25
  def request(method, action, params={}, options={})
26
26
  # Augment in interesting options
27
- options[:saddle] ||= {}
28
- options[:saddle] = {
29
- :call_chain => _path_array(),
30
- :action => action,
31
- }
27
+ options[:call_chain] = _path_array
28
+ options[:action] = action
32
29
  @requester.send(method, _path(action), params, options)
33
30
  end
34
31
 
@@ -87,7 +84,7 @@ module Saddle
87
84
  if defined?(self.class::ABSOLUTE_PATH)
88
85
  [self.class::ABSOLUTE_PATH]
89
86
  else
90
- _path_array()
87
+ _path_array
91
88
  end
92
89
  # Join it with the action
93
90
  paths = pre_action_paths + [action]
@@ -97,7 +94,7 @@ module Saddle
97
94
  end
98
95
 
99
96
  def _path_array
100
- _endpoint_chain().map(&:relative_path).compact
97
+ _endpoint_chain.map(&:relative_path).compact
101
98
  end
102
99
 
103
100
  # Get the parent chain that led to this endpoint
@@ -108,7 +105,7 @@ module Saddle
108
105
  chain << node
109
106
  node = node.parent
110
107
  end
111
- chain.reverse()
108
+ chain.reverse
112
109
  end
113
110
 
114
111
  # If the parent is not an endpoint, it is a root node
@@ -0,0 +1,15 @@
1
+ module Saddle
2
+ # Same as the standard Faraday::RackBuilder, but also allows passing saddle options to the env.
3
+ class RackBuilder < ::Faraday::RackBuilder
4
+ def saddle_options
5
+ @saddle_options ||= {}
6
+ end
7
+
8
+ def build_env(connection, request)
9
+ env = super
10
+ env[:saddle] = saddle_options.deep_merge(request.saddle_options)
11
+ env
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ # Allow saddle options to be accessible through Faraday::Request.
2
+ Faraday::Request.instance_eval do
3
+ attr_accessor :saddle_options
4
+ end
@@ -14,17 +14,17 @@ module Saddle
14
14
  TYPE_URLENCODED = 'application/x-www-form-urlencoded'.freeze
15
15
 
16
16
  def call(env)
17
- if env[:request][:client_options][:oauth1] &&
18
- env[:request][:client_options][:oauth1][:consumer_key] &&
19
- env[:request][:client_options][:oauth1][:consumer_secret] &&
20
- env[:request][:client_options][:oauth1][:token] &&
21
- env[:request][:client_options][:oauth1][:token_secret]
17
+ if env[:saddle][:client_options][:oauth1] &&
18
+ env[:saddle][:client_options][:oauth1][:consumer_key] &&
19
+ env[:saddle][:client_options][:oauth1][:consumer_secret] &&
20
+ env[:saddle][:client_options][:oauth1][:token] &&
21
+ env[:saddle][:client_options][:oauth1][:token_secret]
22
22
 
23
23
  env[:request_headers]['Authorization'] ||= SimpleOAuth::Header.new(
24
24
  env[:method],
25
25
  env[:url].to_s,
26
26
  filtered_body_params(env),
27
- env[:request][:client_options][:oauth1]
27
+ env[:saddle][:client_options][:oauth1]
28
28
  ).to_s
29
29
  end
30
30
 
@@ -16,10 +16,10 @@ module Saddle
16
16
  end
17
17
 
18
18
  def call(env)
19
- if env[:request][:client_options][@key_name.to_sym]
19
+ if env[:saddle][:client_options][@key_name.to_sym]
20
20
  new_query = []
21
21
  new_query << env[:url].query if env[:url].query
22
- new_query << "#{@key_name}=#{CGI.escape(env[:request][:client_options][@key_name.to_sym].to_s)}"
22
+ new_query << "#{@key_name}=#{CGI.escape(env[:saddle][:client_options][@key_name.to_sym].to_s)}"
23
23
  env[:url].query = new_query.join('&')
24
24
  end
25
25
 
@@ -9,8 +9,8 @@ module Saddle
9
9
 
10
10
  class ExtraEnv < Faraday::Middleware
11
11
  def call(env)
12
- if env[:request][:client_options][:extra_env]
13
- env.merge!(env[:request][:client_options][:extra_env])
12
+ if env[:saddle][:client_options][:extra_env]
13
+ env.merge!(env[:saddle][:client_options][:extra_env])
14
14
  end
15
15
 
16
16
  @app.call env
@@ -15,7 +15,7 @@ module Saddle
15
15
  @app.call(env)
16
16
  rescue => e
17
17
  if defined?(Rails.logger)
18
- Rails.logger.error("#{env[:request][:saddle][:client].name} error: #{e}")
18
+ Rails.logger.error("#{env[:saddle][:client].name} error: #{e}")
19
19
  end
20
20
  # Re-raise the error
21
21
  raise
@@ -33,16 +33,16 @@ module Saddle
33
33
 
34
34
  def call(env)
35
35
  # Try to build up a path for the STATSD logging
36
- if env[:request][:statsd_path]
37
- statsd_path = env[:request][:statsd_path]
38
- elsif env[:request][:saddle]
36
+ if env[:saddle][:statsd_path]
37
+ statsd_path = env[:saddle][:statsd_path]
38
+ elsif env[:saddle][:client]
39
39
  statsd_path_components = [
40
40
  'saddle',
41
- env[:request][:saddle][:client].name.underscore,
41
+ env[:saddle][:client].name.underscore,
42
42
  ]
43
- if env[:request][:saddle][:call_chain] && env[:request][:saddle][:action]
44
- statsd_path_components += env[:request][:saddle][:call_chain]
45
- statsd_path_components << env[:request][:saddle][:action]
43
+ if env[:saddle][:call_chain] && env[:saddle][:action]
44
+ statsd_path_components += env[:saddle][:call_chain]
45
+ statsd_path_components << env[:saddle][:action]
46
46
  else
47
47
  statsd_path_components << 'raw'
48
48
  statsd_path_components << "#{env[:url].host}#{env[:url].path}"
@@ -1,7 +1,5 @@
1
1
  require 'faraday'
2
2
 
3
-
4
-
5
3
  module Saddle
6
4
  module Middleware
7
5
  module Request
@@ -15,12 +13,8 @@ module Saddle
15
13
  CONTENT_TYPE = 'Content-Type'.freeze
16
14
  MIME_TYPE = 'application/json'.freeze
17
15
 
18
- dependency do
19
- require 'json' unless defined?(::JSON)
20
- end
21
-
22
16
  def call(env)
23
- if env[:request][:request_style] == :json
17
+ if env[:saddle][:request_style] == :json
24
18
  # Make sure we're working with a valid body that's not a String
25
19
  if env[:body] and !env[:body].respond_to?(:to_str)
26
20
  env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
@@ -10,8 +10,8 @@ module Saddle
10
10
 
11
11
  class PathPrefix < Faraday::Middleware
12
12
  def call(env)
13
- if env[:request][:client_options][:path_prefix]
14
- env[:url].path = "/#{env[:request][:client_options][:path_prefix]}#{env[:url].path}"
13
+ if env[:saddle][:client_options][:path_prefix]
14
+ env[:url].path = "/#{env[:saddle][:client_options][:path_prefix]}#{env[:url].path}"
15
15
  end
16
16
 
17
17
  @app.call env
@@ -17,13 +17,13 @@ module Saddle
17
17
  end
18
18
 
19
19
  def call(env)
20
- retries = env[:request][:num_retries] || 0
21
- backoff = env[:request][:retry_backoff] || 0.050 # in seconds
20
+ retries = env[:saddle][:num_retries] || 0
21
+ backoff = env[:saddle][:retry_backoff] || 0.050 # in seconds
22
22
  begin
23
23
  @app.call(self.class.deep_copy(env))
24
24
  rescue => e
25
25
  # Only retry for GET or if the request is marked as idempotent
26
- if env[:method] == :get || env[:request][:idempotent]
26
+ if env[:method] == :get || env[:saddle][:idempotent]
27
27
  unless @ignored_exceptions.include?(e.class)
28
28
  # Retry a limited number of times
29
29
  if retries > 0
@@ -40,7 +40,11 @@ module Saddle
40
40
  end
41
41
 
42
42
  def self.deep_copy(value)
43
- if value.is_a?(Hash)
43
+ if value.is_a?(Struct)
44
+ result = value.clone
45
+ value.each{|k, v| result.send("#{k}=", deep_copy(v))}
46
+ result
47
+ elsif value.is_a?(Hash)
44
48
  result = value.clone
45
49
  value.each{|k, v| result[k] = deep_copy(v)}
46
50
  result
@@ -24,7 +24,7 @@ module Saddle
24
24
 
25
25
 
26
26
  def call(env)
27
- if env[:request][:request_style] == :urlencoded
27
+ if env[:saddle][:request_style] == :urlencoded
28
28
  # Make sure we're working with a valid body that's not a String
29
29
  if env[:body] and !env[:body].respond_to?(:to_str)
30
30
  if has_multipart?(env[:body])
@@ -13,7 +13,7 @@ module Saddle
13
13
  user_agent = nil
14
14
  # Build a user agent that looks like 'SaddleExample 0.0.1'
15
15
  begin
16
- user_agent = client_name = env[:request][:saddle][:client].name
16
+ user_agent = client_name = env[:saddle][:client].name
17
17
  parent_module = client_name.split('::')[0..-2].join('::').constantize
18
18
  if parent_module
19
19
  if defined?(parent_module::VERSION)
@@ -13,7 +13,7 @@ module Saddle
13
13
  begin
14
14
  @app.call(env)
15
15
  rescue
16
- if res = env[:request][:default_response]
16
+ if res = env[:saddle][:default_response]
17
17
  return ::Faraday::Response.new(:body => res)
18
18
  else
19
19
  raise
@@ -1,7 +1,5 @@
1
1
  require 'faraday'
2
2
 
3
-
4
-
5
3
  module Saddle
6
4
  module Middleware
7
5
  module Response
@@ -12,10 +10,6 @@ module Saddle
12
10
  CONTENT_TYPE = 'Content-Type'.freeze
13
11
  MIME_TYPE = 'application/json'.freeze
14
12
 
15
- dependency do
16
- require 'json' unless defined?(::JSON)
17
- end
18
-
19
13
  def call(env)
20
14
  result = @app.call(env)
21
15
 
@@ -11,9 +11,9 @@ module Saddle
11
11
 
12
12
  case result.status
13
13
  when 404
14
- raise Faraday::Error::ResourceNotFound, response_values(result)
14
+ raise Faraday::ResourceNotFound, response_values(result)
15
15
  when 400...600
16
- raise Faraday::Error::ClientError, response_values(result)
16
+ raise Faraday::ClientError, response_values(result)
17
17
  end
18
18
 
19
19
  result
@@ -13,13 +13,13 @@ module Saddle
13
13
  class RubyTimeout < Faraday::Middleware
14
14
 
15
15
  def call(env)
16
- timeout = env[:request][:hard_timeout] # nil or 0 means no timeout
16
+ timeout = env[:saddle][:hard_timeout] # nil or 0 means no timeout
17
17
  Timeout.timeout(timeout, Saddle::TimeoutError) do
18
18
  @app.call(env)
19
19
  end
20
20
  # It is possible that faraday will catch the timeout first and throw
21
21
  # this exception, rethrow as a class derived from standard error.
22
- rescue Faraday::Error::TimeoutError
22
+ rescue Faraday::TimeoutError
23
23
  raise Saddle::TimeoutError
24
24
  end
25
25
 
@@ -1,8 +1,9 @@
1
1
  require 'active_support/core_ext/hash'
2
+ require 'active_support/notifications'
2
3
 
3
4
  require 'faraday'
4
- require 'faraday_middleware'
5
-
5
+ require 'saddle/faraday/request'
6
+ require 'saddle/faraday/rack_builder'
6
7
 
7
8
  require 'saddle/middleware/request/encode_json'
8
9
  require 'saddle/middleware/request/path_prefix'
@@ -79,7 +80,7 @@ module Saddle
79
80
  # Make a GET request
80
81
  def get(url, params={}, options={})
81
82
  response = connection.get do |req|
82
- req.options.deep_merge!(options)
83
+ req.saddle_options = options
83
84
  req.body = options[:body] if options.has_key?(:body)
84
85
  req.url(url, params)
85
86
  end
@@ -89,7 +90,7 @@ module Saddle
89
90
  # Make a POST request
90
91
  def post(url, data={}, options={})
91
92
  response = connection.post do |req|
92
- req.options.deep_merge!(options)
93
+ req.saddle_options = options
93
94
  req.url(url)
94
95
  req.body = data
95
96
  end
@@ -99,7 +100,7 @@ module Saddle
99
100
  # Make a PUT request
100
101
  def put(url, data={}, options={})
101
102
  response = connection.put do |req|
102
- req.options.deep_merge!(options)
103
+ req.saddle_options = options
103
104
  req.url(url)
104
105
  req.body = data
105
106
  end
@@ -109,7 +110,7 @@ module Saddle
109
110
  # Make a DELETE request
110
111
  def delete(url, params={}, options={})
111
112
  response = connection.delete do |req|
112
- req.options.deep_merge!(options)
113
+ req.saddle_options = options
113
114
  req.url(url, params)
114
115
  end
115
116
  handle_response(response)
@@ -131,61 +132,59 @@ module Saddle
131
132
 
132
133
  # Build a connection instance, wrapped in the middleware that we want
133
134
  def connection
134
- @connection ||= Faraday.new(base_url) do |builder|
135
+ @connection ||= Faraday.new(base_url, :builder_class => Saddle::RackBuilder) do |connection|
135
136
  # Include the requester level options
136
- builder.options[:client_options] = @options
137
+ connection.builder.saddle_options[:client_options] = @options
137
138
 
138
139
  # Config options
139
- builder.options[:timeout] = @timeout
140
- builder.options[:request_style] = @request_style
141
- builder.options[:num_retries] = @num_retries
142
- builder.options[:saddle] = {
143
- :client => @parent_client,
144
- }
140
+ connection.options[:timeout] = @timeout
141
+ connection.builder.saddle_options[:request_style] = @request_style
142
+ connection.builder.saddle_options[:num_retries] = @num_retries
143
+ connection.builder.saddle_options[:client] = @parent_client
145
144
 
146
145
  # Support default return values upon exception
147
- builder.use(Saddle::Middleware::Response::DefaultResponse)
146
+ connection.use(Saddle::Middleware::Response::DefaultResponse)
148
147
 
149
148
  # Hard timeout on the entire request
150
- builder.use(Saddle::Middleware::RubyTimeout)
149
+ connection.use(Saddle::Middleware::RubyTimeout)
151
150
 
152
151
  # Set up a user agent
153
- builder.use(Saddle::Middleware::Request::UserAgent)
152
+ connection.use(Saddle::Middleware::Request::UserAgent)
154
153
 
155
154
  # Set up the path prefix if needed
156
- builder.use(Saddle::Middleware::Request::PathPrefix)
155
+ connection.use(Saddle::Middleware::Request::PathPrefix)
157
156
 
158
157
  # Apply additional implementation-specific middlewares
159
158
  @additional_middlewares.each do |m|
160
- m[:args] ? builder.use(m[:klass], *m[:args]) : builder.use(m[:klass])
159
+ m[:args] ? connection.use(m[:klass], *m[:args]) : connection.use(m[:klass])
161
160
  end
162
161
 
163
162
  # Request encoding
164
- builder.use(Saddle::Middleware::Request::JsonEncoded)
165
- builder.use(Saddle::Middleware::Request::UrlEncoded)
163
+ connection.use(Saddle::Middleware::Request::JsonEncoded)
164
+ connection.use(Saddle::Middleware::Request::UrlEncoded)
166
165
 
167
166
  # Automatic retries
168
- builder.use(Saddle::Middleware::Request::Retry)
167
+ connection.use(Saddle::Middleware::Request::Retry)
169
168
 
170
169
  # Raise exceptions on 4xx and 5xx errors
171
- builder.use(Saddle::Middleware::Response::RaiseError)
170
+ connection.use(Saddle::Middleware::Response::RaiseError)
172
171
 
173
172
  # Handle parsing out the response if it's JSON
174
- builder.use(Saddle::Middleware::Response::ParseJson)
173
+ connection.use(Saddle::Middleware::Response::ParseJson)
175
174
 
176
175
  # Set up instrumentation around the adapter for extensibility
177
- builder.use(FaradayMiddleware::Instrumentation)
176
+ connection.request :instrumentation
178
177
 
179
178
  # Add in extra env data if needed
180
- builder.use(Saddle::Middleware::ExtraEnv)
179
+ connection.use(Saddle::Middleware::ExtraEnv)
181
180
 
182
181
  # Set up our adapter
183
182
  if @stubs.nil?
184
183
  # Use the default adapter
185
- builder.adapter(@http_adapter[:key], *@http_adapter[:args])
184
+ connection.adapter(@http_adapter[:key], *@http_adapter[:args])
186
185
  else
187
186
  # Use the test adapter
188
- builder.adapter(:test, @stubs)
187
+ connection.adapter(:test, @stubs)
189
188
  end
190
189
  end
191
190
  end
@@ -1,3 +1,3 @@
1
1
  module Saddle
2
- VERSION = '0.0.53'
2
+ VERSION = '0.2.0'
3
3
  end
data/saddle.gemspec CHANGED
@@ -21,13 +21,11 @@ Gem::Specification.new do |s|
21
21
  s.files = `git ls-files`.split($\)
22
22
  s.executables = ['saddle']
23
23
  s.test_files = s.files.grep(%r{^(spec)/})
24
-
25
- if RUBY_VERSION < '1.9'
26
- s.add_dependency 'activesupport', '~> 3.0'
27
- else
28
- s.add_dependency 'activesupport', '>= 3.0'
29
- end
30
24
 
31
- s.add_dependency 'faraday', '~> 0.8.7'
32
- s.add_dependency 'faraday_middleware', '~> 0.9.0'
25
+ s.required_ruby_version = '>= 2.6'
26
+
27
+ s.add_dependency 'activesupport', '>= 3.2'
28
+ s.add_dependency 'faraday', '~> 2.1'
29
+
30
+ s.add_development_dependency 'appraisal'
33
31
  end
@@ -4,11 +4,11 @@ describe Saddle::BaseEndpoint do
4
4
  let(:base_endpoint) { Saddle::BaseEndpoint.new(Saddle::Client.create) }
5
5
 
6
6
  it 'can define singleton methods' do
7
- expect(base_endpoint.respond_to?(:define_singleton_method)).to be_true
7
+ expect(base_endpoint.respond_to?(:define_singleton_method)).to be_truthy
8
8
  end
9
9
 
10
10
  it 'responds to any defined singleton methods' do
11
11
  base_endpoint.define_singleton_method(:my_method) { true }
12
- expect(base_endpoint.my_method).to be_true
12
+ expect(base_endpoint.my_method).to be_truthy
13
13
  end
14
14
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
 
4
- describe 'FaradayMiddleware::Instrumentation' do
4
+ describe 'Faraday::Instrumentation' do
5
5
 
6
6
  context "test integration of instrumentation middleware" do
7
7
 
@@ -72,7 +72,7 @@ describe Saddle::Client do
72
72
  }
73
73
  expect {
74
74
  @default_client.requester.post(url)
75
- }.to raise_error(Faraday::Error::ClientError)
75
+ }.to raise_error(Faraday::ClientError)
76
76
  end
77
77
 
78
78
  it "should retry if it is marked as idempotent" do
@@ -26,7 +26,7 @@ describe Saddle::Client do
26
26
  end
27
27
 
28
28
  it "should request properly with params in the body" do
29
- @stubs.send(:new_stub, :get, '/test', "body data") {
29
+ @stubs.send(:new_stub, :get, '/test', {}, "body data") {
30
30
  [
31
31
  200,
32
32
  {},
metadata CHANGED
@@ -1,57 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saddle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.53
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Lewis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-13 00:00:00.000000000 Z
11
+ date: 2023-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '3.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '3.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: faraday
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.8.7
33
+ version: '2.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.8.7
40
+ version: '2.1'
41
41
  - !ruby/object:Gem::Dependency
42
- name: faraday_middleware
42
+ name: appraisal
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.9.0
48
- type: :runtime
47
+ version: '0'
48
+ type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.9.0
54
+ version: '0'
55
55
  description: Makes writing API clients as easy as giving high fives
56
56
  email: mike.lewis@airbnb.com
57
57
  executables:
@@ -59,9 +59,11 @@ executables:
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
- - .gitignore
63
- - .rspec
64
- - .travis.yml
62
+ - ".github/workflows/ci.yml"
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - Appraisals
65
67
  - CHANGELOG.md
66
68
  - Gemfile
67
69
  - LICENSE
@@ -83,10 +85,22 @@ files:
83
85
  - bin/template/spec/middleware/exception_raiser_spec.rb
84
86
  - bin/template/spec/spec_helper.rb
85
87
  - bin/template/spec/stub/stub_spec.rb
88
+ - gemfiles/activesupport_3.2.gemfile
89
+ - gemfiles/activesupport_4.0.gemfile
90
+ - gemfiles/activesupport_4.1.gemfile
91
+ - gemfiles/activesupport_4.2.gemfile
92
+ - gemfiles/activesupport_5.0.gemfile
93
+ - gemfiles/activesupport_5.1.gemfile
94
+ - gemfiles/activesupport_5.2.gemfile
95
+ - gemfiles/activesupport_6.0.gemfile
96
+ - gemfiles/activesupport_6.1.gemfile
97
+ - gemfiles/activesupport_7.0.gemfile
86
98
  - lib/saddle.rb
87
99
  - lib/saddle/client_attributes.rb
88
100
  - lib/saddle/endpoint.rb
89
101
  - lib/saddle/errors.rb
102
+ - lib/saddle/faraday/rack_builder.rb
103
+ - lib/saddle/faraday/request.rb
90
104
  - lib/saddle/method_tree_builder.rb
91
105
  - lib/saddle/middleware/authentication/oauth1.rb
92
106
  - lib/saddle/middleware/authentication/oauth2.rb
@@ -130,17 +144,16 @@ require_paths:
130
144
  - lib
131
145
  required_ruby_version: !ruby/object:Gem::Requirement
132
146
  requirements:
133
- - - ! '>='
147
+ - - ">="
134
148
  - !ruby/object:Gem::Version
135
- version: '0'
149
+ version: '2.6'
136
150
  required_rubygems_version: !ruby/object:Gem::Requirement
137
151
  requirements:
138
- - - ! '>='
152
+ - - ">="
139
153
  - !ruby/object:Gem::Version
140
154
  version: '0'
141
155
  requirements: []
142
- rubyforge_project:
143
- rubygems_version: 2.2.2
156
+ rubygems_version: 3.0.3.1
144
157
  signing_key:
145
158
  specification_version: 4
146
159
  summary: A full-featured, generic consumer layer for you to build API client implementations