clientele 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -1
- data/README.md +305 -11
- data/Rakefile +14 -0
- data/lib/clientele/api.rb +12 -11
- data/lib/clientele/configuration.rb +3 -1
- data/lib/clientele/request.rb +16 -4
- data/lib/clientele/request_builder.rb +5 -6
- data/lib/clientele/resource/pagination.rb +3 -2
- data/lib/clientele/resource.rb +22 -13
- data/lib/clientele/version.rb +1 -1
- metadata +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88fca56c3d0d1aeefda397db16761647de0076d7
|
4
|
+
data.tar.gz: e8681f282556c70e74b3390c5c6407a333c82d08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ffd27f7cac3344386bb4873fc2ca5407e4ff5e24a5986f3973f13371b980202818940f452b44fc11c2dad0dc2dea07ac7af61c8f99ba1a307b70bc01364ca7de
|
7
|
+
data.tar.gz: 982447bbb8ce83d68e0278eb5e264c9c978134d262df35d8bde3cf8c65024fd9857c33cea11644a5fb1e994b81594b242ccd0b60cee8af187afab6361ef5adb2
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,27 +1,321 @@
|
|
1
1
|
Clientele
|
2
2
|
=========
|
3
3
|
|
4
|
-
> *
|
4
|
+
> *Create Ruby API clients with ease.*
|
5
5
|
|
6
|
-
## Installation
|
7
6
|
|
8
|
-
Add this line to your application's Gemfile:
|
9
7
|
|
10
|
-
|
8
|
+
Usage
|
9
|
+
-----
|
11
10
|
|
12
|
-
|
11
|
+
Clientele makes it easy to create feature-rich ruby API clients with minimal boilerplate.
|
13
12
|
|
14
|
-
|
13
|
+
In this example, we'll be making an API client for our popular new service at example.com.
|
15
14
|
|
16
|
-
Or install it yourself as:
|
17
15
|
|
18
|
-
|
16
|
+
### Creating an API Client
|
19
17
|
|
20
|
-
|
18
|
+
Since we'll be distributing this client as a gem, we'll use bundler to get our boilerplate code set up:
|
21
19
|
|
22
|
-
|
20
|
+
```bash
|
21
|
+
bundle gem example-api
|
22
|
+
cd example-api
|
23
|
+
```
|
23
24
|
|
24
|
-
|
25
|
+
Next we'll add `clientele` as a dependency to our gemspec.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# example-api.gemspec
|
29
|
+
|
30
|
+
Gem::Specification.new do |spec|
|
31
|
+
|
32
|
+
# ...
|
33
|
+
|
34
|
+
spec.add_dependency 'clientele'
|
35
|
+
|
36
|
+
# ...
|
37
|
+
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Then install `clientele`.
|
42
|
+
|
43
|
+
```bash
|
44
|
+
bundle install
|
45
|
+
```
|
46
|
+
|
47
|
+
Finally, we can create our API Client class. We must configure it with a url to use as the base of our API.
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
# lib/example/api.rb
|
51
|
+
|
52
|
+
require 'clientele'
|
53
|
+
|
54
|
+
module Example
|
55
|
+
class API < Clientele::API
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
|
62
|
+
### Making Requests
|
63
|
+
|
64
|
+
Now that we have a client class, we can construct requests off of it to our API by providing the anatomy of an HTTP request.
|
65
|
+
|
66
|
+
#### Initializing a Client
|
67
|
+
|
68
|
+
Creating a client instance is as simple as passing in any configuration options into `new`. See the Configuration section for more options.
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
client = Example::API.new(root_url: 'http://example.com')
|
72
|
+
```
|
73
|
+
|
74
|
+
Alternatively, you can use the `client` method to lazily initialize and access a global API client if you're not concerned about thread safety, or just experimenting with an API.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
# Return client with default configuration
|
78
|
+
Example::API.client
|
79
|
+
#=> #<Example::API:0x007f85faa16468>
|
80
|
+
|
81
|
+
# Configure/reconfigure and return global client
|
82
|
+
Example::API.client(root_url: 'http://example.com')
|
83
|
+
#=> #<Example::API:0x007f85faa16468>
|
84
|
+
```
|
85
|
+
|
86
|
+
Future calls to `client` will use this configured instance. Passing options into it will reconfigure this global client.
|
87
|
+
|
88
|
+
Finally, any unknown method calls on the client class attempt to see if the global client responds to them.
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Example::API.foo
|
92
|
+
# will return the result of
|
93
|
+
Example::API.client.foo
|
94
|
+
# provided the client responds to foo.
|
95
|
+
```
|
96
|
+
|
97
|
+
#### Building Requests on Client Instances
|
98
|
+
|
99
|
+
The simplest way to make requests is to call the HTTP verb you want on your client, passing in a hash with everything you need to in the request. For the rest of these examples we'll be using the global client.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
request = Example::API.get(path: 'foo')
|
103
|
+
#=> #<struct Clientele::Request>
|
104
|
+
```
|
105
|
+
|
106
|
+
Clients respond to any of the HTTP verbs found in `Clientele::Request::VERBS`. The resulting request can be triggered with `call` as if a Proc.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
response = Example::API.get(path: 'foo').call
|
110
|
+
#=> #<Faraday::Response>
|
111
|
+
```
|
112
|
+
|
113
|
+
Unlike other options, you can provide path as a direct argument rather than a keyword one.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
Example::API.get(path: 'foo', query: {bar: :baz})
|
117
|
+
# is the same as
|
118
|
+
Example::API.get('foo', query: {bar: :baz})
|
119
|
+
```
|
120
|
+
|
121
|
+
The options used to construct a request are:
|
122
|
+
|
123
|
+
Option | Default | Description
|
124
|
+
------------------------------
|
125
|
+
path | `''` | The url path to build off of `root_url`.
|
126
|
+
query | `{}` | A hash of query string parameters.
|
127
|
+
body | `{}` | A hash representing the request payload.
|
128
|
+
headers | `client.configuration.default_headers` | A hash representing the request headers.
|
129
|
+
callback | `nil` | An optional callback `Proc` to pass the response into. If the request constructor receives a block, it will use that as a callback.
|
130
|
+
|
131
|
+
In actuality, these methods will instead return `Clientele::RequestBuilder` instances with your defined request inside. Regardless, the `call` method will invoke them the same.
|
132
|
+
|
133
|
+
Of course, all these features amount to at this point is a verbose HTTP Library. The power of `clientele` comes from using these components to define resources.
|
134
|
+
|
135
|
+
|
136
|
+
### Creating Resources
|
137
|
+
|
138
|
+
Resources inherit from `Clientele::Resource` and map to namespaced endpoints of an API that deal with similar datatypes, as is found often in RESTful APIs.
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
# lib/example/api/resources.rb
|
142
|
+
|
143
|
+
require 'example/api/resources/foo`
|
144
|
+
```
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
# lib/example/api/resources/foo.rb
|
148
|
+
|
149
|
+
module Example
|
150
|
+
class API < Clientele::API
|
151
|
+
module Resources
|
152
|
+
class Foo < Clientele::Resource
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
```
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
# lib/example/api.rb
|
164
|
+
|
165
|
+
require 'lib/example/api/resources'
|
166
|
+
|
167
|
+
module Example
|
168
|
+
class API < Clientele::API
|
169
|
+
|
170
|
+
# ...
|
171
|
+
|
172
|
+
resource Resources::Foo
|
173
|
+
|
174
|
+
# ...
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
```
|
179
|
+
|
180
|
+
Registering this resource on the client allows it to be invoked as a method.
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
Example::API.foos
|
184
|
+
#=> #<Clientele::RequestBuilder>
|
185
|
+
```
|
186
|
+
|
187
|
+
Calling this request will send a `GET` request to `http://example.com/foos' with default headers and no query string parameters.
|
188
|
+
|
189
|
+
Using the request builder API, we can define class methods on the resource that accomplish any HTTP request. If we provide a path it will be appended to the resource's path (ie. `'foo/path'`); otherwise it will send the request to the resource root. For instance, to get an ActiveRecord-inspired request DSL:
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
# lib/example/api/resources/foo.rb
|
193
|
+
|
194
|
+
module Example
|
195
|
+
class API < Clientele::API
|
196
|
+
module Resources
|
197
|
+
class Foo < Clientele::Resource
|
198
|
+
|
199
|
+
class << self
|
200
|
+
|
201
|
+
def all(&callback)
|
202
|
+
get &callback
|
203
|
+
end
|
204
|
+
|
205
|
+
def where(query={}, &callback)
|
206
|
+
get query: query, &callback
|
207
|
+
end
|
208
|
+
|
209
|
+
def create(body={}, &callback)
|
210
|
+
post body: body, &callback
|
211
|
+
end
|
212
|
+
|
213
|
+
def fetch(id, query={}, &callback)
|
214
|
+
get id, query: query, &callback
|
215
|
+
end
|
216
|
+
|
217
|
+
def update(id, body={}, &callback)
|
218
|
+
patch id, body: body, &callback
|
219
|
+
end
|
220
|
+
|
221
|
+
def destroy(id, &callback)
|
222
|
+
delete id, &callback
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
```
|
232
|
+
|
233
|
+
|
234
|
+
### Using Resources
|
235
|
+
|
236
|
+
Introduction
|
237
|
+
|
238
|
+
#### Making Requests to Resources
|
239
|
+
|
240
|
+
#### Making Asyncronous Requests
|
241
|
+
|
242
|
+
#### Chaining Resource Requests
|
243
|
+
|
244
|
+
#### Iterating Across Paginated Resources
|
245
|
+
|
246
|
+
|
247
|
+
### Configuration
|
248
|
+
|
249
|
+
`Clientele::API` instances each have their own configuration that they receive from a class-level configuration object. Both the class level and instance level configurations can be customized on demand by you, the API client developer, or consumers of your client.
|
250
|
+
|
251
|
+
#### Configuration Options
|
252
|
+
|
253
|
+
Option | Default | Description
|
254
|
+
------------------------------
|
255
|
+
root_url | Required | The root url against which all requests are made.
|
256
|
+
logger | `Logger.new($stdout)` | The logger for `clientele` to use.
|
257
|
+
adapter | `Faraday.default_adapter` | The `faraday` adapter to use.
|
258
|
+
headers | `{}` | Headers to use with every request.
|
259
|
+
hashify_content_type | /\bjson$/ | A regex `faraday` applies to response content types to determine whether or not to try to convert the payload into a hash.
|
260
|
+
follow_redirects | `true` | Whether or not to follow redirects.
|
261
|
+
redirect_limit | `5` | How deep to follow redirects.
|
262
|
+
|
263
|
+
#### Default Library Configuration
|
264
|
+
|
265
|
+
To override `clientele`'s default options within your library, use the `configure` class method on your API client. You'll probably want to do this for at least the `root_url` option since it has no default.
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
#lib/example/api.rb
|
269
|
+
require 'clientele'
|
270
|
+
|
271
|
+
module Example
|
272
|
+
class API < Clientele::API
|
273
|
+
|
274
|
+
configure do |config|
|
275
|
+
|
276
|
+
# Required options
|
277
|
+
config.root_url = "http://example.com"
|
278
|
+
|
279
|
+
# Optional overrides
|
280
|
+
config.headers = {
|
281
|
+
'Accept' => 'application/json',
|
282
|
+
'Content-Type' => 'application/json',
|
283
|
+
}
|
284
|
+
# must add 'net-http-persistent' to gemspec to use:
|
285
|
+
config.adapter = :net_http_peristent
|
286
|
+
|
287
|
+
# Custom configuration values
|
288
|
+
config.custom = :foobar
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
end
|
294
|
+
```
|
295
|
+
|
296
|
+
You'll probably want to include the table above, alongside any modifications or additions, in your client's documentation.
|
297
|
+
|
298
|
+
#### Default User Configuration
|
299
|
+
|
300
|
+
Users of your API Client can also access the class level `configure` method to change default configuration options within their project. This should be done early on in the script, library loading stage, or boot process so it can take effect before any clients are instanciated.
|
301
|
+
|
302
|
+
Rails users would put this in an initializer.
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
#my_app/config/initializers/example-api.rb
|
306
|
+
require 'example/api'
|
307
|
+
|
308
|
+
Example::API.configure do |config|
|
309
|
+
config.root_url = 'http://dev.example.com'
|
310
|
+
end
|
311
|
+
```
|
312
|
+
|
313
|
+
You may also wish to document how to do this in your gem.
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
Contributing
|
318
|
+
------------
|
25
319
|
|
26
320
|
1. Fork it ( https://github.com/[my-github-username]/clientele/fork )
|
27
321
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
data/Rakefile
CHANGED
@@ -1,2 +1,16 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
|
+
desc "Open a pry console preloaded with this library"
|
4
|
+
task console: 'console:pry'
|
5
|
+
|
6
|
+
namespace :console do
|
7
|
+
|
8
|
+
task :pry do
|
9
|
+
sh "bundle exec pry -I lib -r clientele.rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
task :irb do
|
13
|
+
sh "bundle exec irb -I lib -r clientele.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/lib/clientele/api.rb
CHANGED
@@ -16,7 +16,6 @@ module Clientele
|
|
16
16
|
|
17
17
|
extend SingleForwardable
|
18
18
|
def_delegator :configuration, :logger
|
19
|
-
def_delegators :request, *Request::VERBS
|
20
19
|
|
21
20
|
class_attribute :resources, instance_predicate: false
|
22
21
|
self.resources = {}
|
@@ -25,7 +24,13 @@ module Clientele
|
|
25
24
|
|
26
25
|
def client(opts={})
|
27
26
|
autoconfigure!
|
28
|
-
@client
|
27
|
+
if @client
|
28
|
+
@client.tap do |client|
|
29
|
+
client.configuration.load_hash(opts)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
@client = new(opts)
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
36
|
def logger
|
@@ -34,7 +39,7 @@ module Clientele
|
|
34
39
|
end
|
35
40
|
|
36
41
|
def resource(klass)
|
37
|
-
self.resources = resources.merge(
|
42
|
+
self.resources = resources.merge(klass.method_name.to_sym => klass)
|
38
43
|
end
|
39
44
|
|
40
45
|
private
|
@@ -63,21 +68,17 @@ module Clientele
|
|
63
68
|
self.configuration.load_hash opts
|
64
69
|
end
|
65
70
|
|
66
|
-
protected
|
67
|
-
|
68
|
-
def request
|
69
|
-
Request
|
70
|
-
end
|
71
|
-
|
72
71
|
private
|
73
72
|
|
74
73
|
def respond_to_missing?(method_name, include_private=false)
|
75
|
-
resources.keys.include?(method_name) or super
|
74
|
+
resources.keys.include?(method_name) or Request::VERBS.include?(method_name) or super
|
76
75
|
end
|
77
76
|
|
78
77
|
def method_missing(method_name, *args, &block)
|
79
78
|
if resources.keys.include? method_name
|
80
|
-
RequestBuilder.new(
|
79
|
+
RequestBuilder.new(resources[method_name], client: self)
|
80
|
+
elsif Request::VERBS.include? method_name
|
81
|
+
RequestBuilder.new(Request.send(method_name, *args), client: self)
|
81
82
|
else; super; end
|
82
83
|
end
|
83
84
|
|
@@ -5,13 +5,15 @@ require 'faraday'
|
|
5
5
|
module Clientele
|
6
6
|
class Configuration < BlockParty::Configuration
|
7
7
|
|
8
|
-
attr_accessor :logger, :adapter, :headers, :hashify_content_type, :root_url
|
8
|
+
attr_accessor :logger, :adapter, :headers, :hashify_content_type, :root_url, :follow_redirects, :redirect_limit
|
9
9
|
|
10
10
|
def initialize
|
11
11
|
self.logger = Logger.new($stdout)
|
12
12
|
self.adapter = Faraday.default_adapter
|
13
13
|
self.headers = {}
|
14
14
|
self.hashify_content_type = /\bjson$/
|
15
|
+
self.follow_redirects = true
|
16
|
+
self.redirect_limit = 5
|
15
17
|
end
|
16
18
|
|
17
19
|
end
|
data/lib/clientele/request.rb
CHANGED
@@ -12,8 +12,14 @@ module Clientele
|
|
12
12
|
|
13
13
|
VERBS = %i[get post put patch delete]
|
14
14
|
VERBS.each do |verb|
|
15
|
-
define_singleton_method verb do |opts = {}, &callback|
|
16
|
-
new
|
15
|
+
define_singleton_method verb do |path = '', opts = {}, &callback|
|
16
|
+
new(
|
17
|
+
opts.tap do |opts|
|
18
|
+
opts.merge!(verb: __method__)
|
19
|
+
# opts.merge!(path: path) unless opts[:path]
|
20
|
+
# opts.merge!(callback: callback) if callback
|
21
|
+
end
|
22
|
+
)
|
17
23
|
end
|
18
24
|
end
|
19
25
|
|
@@ -39,7 +45,6 @@ module Clientele
|
|
39
45
|
def call
|
40
46
|
callback ? callback.call(response) : response
|
41
47
|
end
|
42
|
-
alias_method :~, :call
|
43
48
|
|
44
49
|
def + other
|
45
50
|
self.class.new(
|
@@ -66,8 +71,15 @@ module Clientele
|
|
66
71
|
|
67
72
|
def faraday_client
|
68
73
|
Faraday.new(options[:root_url]) do |conn|
|
74
|
+
|
75
|
+
conn.use FaradayMiddleware::FollowRedirects, limit: options[:redirect_limit] if options[:follow_redirects]
|
76
|
+
|
77
|
+
conn.request :url_encoded
|
78
|
+
|
69
79
|
conn.response :rashify
|
80
|
+
conn.response :logger
|
70
81
|
conn.response :json, content_type: options[:hashify_content_type], preserve_raw: true
|
82
|
+
|
71
83
|
conn.adapter options[:adapter]
|
72
84
|
end
|
73
85
|
end
|
@@ -76,7 +88,7 @@ module Clientele
|
|
76
88
|
def defaults
|
77
89
|
{
|
78
90
|
verb: :get,
|
79
|
-
path:
|
91
|
+
path: '',
|
80
92
|
query: {},
|
81
93
|
body: {},
|
82
94
|
headers: {},
|
@@ -9,14 +9,13 @@ module Clientele
|
|
9
9
|
alias_method :to_a, :stack
|
10
10
|
|
11
11
|
def initialize(*request_components, client: API.client)
|
12
|
-
@stack =
|
12
|
+
@stack = request_components.flatten
|
13
13
|
@client = client
|
14
14
|
end
|
15
15
|
|
16
16
|
def call
|
17
17
|
build.call
|
18
18
|
end
|
19
|
-
alias_method :~, :call
|
20
19
|
|
21
20
|
protected
|
22
21
|
|
@@ -49,15 +48,15 @@ module Clientele
|
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
52
|
-
def
|
53
|
-
merge_paths(stack.map(&:
|
51
|
+
def path
|
52
|
+
merge_paths(stack.map(&:path))
|
54
53
|
end
|
55
54
|
|
56
55
|
private
|
57
56
|
|
58
57
|
def method_missing(method_name, *args, &block)
|
59
|
-
if
|
60
|
-
tap { |builder| builder.stack <<
|
58
|
+
if client.resources.keys.include? method_name
|
59
|
+
tap { |builder| builder.stack << client.resources[method_name] }
|
61
60
|
elsif stack.last.respond_to? :each_with_builder and method_name == :each
|
62
61
|
stack.last.each_with_builder(self, &block)
|
63
62
|
elsif stack.last.respond_to? method_name, false
|
@@ -22,11 +22,12 @@ module Clientele
|
|
22
22
|
Proc.new do
|
23
23
|
|
24
24
|
def next_page(request)
|
25
|
-
request.query[:page]
|
25
|
+
request.query[:page] ||= 0
|
26
|
+
request.query[:page] += 1
|
26
27
|
end
|
27
28
|
|
28
29
|
def total(response)
|
29
|
-
response.headers.fetch('x-total-count', Float::INFINITY)
|
30
|
+
response.headers.fetch('x-total-count', Float::INFINITY).to_f
|
30
31
|
end
|
31
32
|
|
32
33
|
def pages(response)
|
data/lib/clientele/resource.rb
CHANGED
@@ -12,33 +12,42 @@ module Clientele
|
|
12
12
|
|
13
13
|
class << self
|
14
14
|
include Clientele::Utils
|
15
|
+
|
15
16
|
attr_reader :subclasses
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
path: merge_paths(
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
)
|
17
|
+
|
18
|
+
Request::VERBS.each do |verb|
|
19
|
+
define_method verb do |path_segment = '', opts = {}, &callback|
|
20
|
+
path_segment, opts = opts[:path].to_s, path_segment if path_segment.is_a? Hash
|
21
|
+
Request.new(opts.merge(path: merge_paths(path, path_segment || opts[:path].to_s)), &callback)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def request(verb, path = '', opts = {}, &callback)
|
26
|
+
send verb, path, opts, &callback
|
27
27
|
end
|
28
28
|
|
29
29
|
def to_request(options={}, &callback)
|
30
|
-
|
30
|
+
get options: options, &callback
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def default_path
|
34
34
|
self.name.split('::').last.pluralize.underscore
|
35
35
|
end
|
36
36
|
|
37
|
+
def path
|
38
|
+
@path || default_path
|
39
|
+
end
|
40
|
+
|
41
|
+
def method_name
|
42
|
+
@method_name || path
|
43
|
+
end
|
44
|
+
|
37
45
|
private
|
38
46
|
|
39
47
|
def inherited(base)
|
40
48
|
@subclasses << base
|
41
49
|
end
|
50
|
+
|
42
51
|
end
|
43
52
|
|
44
53
|
end
|
data/lib/clientele/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clientele
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Keele
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -187,4 +187,3 @@ signing_key:
|
|
187
187
|
specification_version: 4
|
188
188
|
summary: DSL for creating RESTful API clients for external services.
|
189
189
|
test_files: []
|
190
|
-
has_rdoc:
|