api_client 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +129 -0
- data/lib/api_client/base.rb +7 -1
- data/lib/api_client/version.rb +1 -1
- data/spec/api_client/base_spec.rb +24 -3
- data/spec/api_client/connection/basic_spec.rb +12 -4
- metadata +25 -9
data/README.md
CHANGED
@@ -7,6 +7,135 @@ Basically you should be able to build a client for any HTTP based API, without t
|
|
7
7
|
|
8
8
|
Current state is alpha - it works, but the query interface is not final and is subject to change at any time. Hell, even the can even change without prior notice. You were warned.
|
9
9
|
|
10
|
+
## How API Client works
|
11
|
+
|
12
|
+
ApiClient gives you two classes that you can inherit from:
|
13
|
+
|
14
|
+
* ApiClient::Base
|
15
|
+
|
16
|
+
This class gives you the most basic access. It is a Hashie::Mash
|
17
|
+
subclass. On the class level, it exposes a variety of request
|
18
|
+
methods (like get, post, put, delete)
|
19
|
+
|
20
|
+
* ApiClient::Resource::Base
|
21
|
+
|
22
|
+
This class extends ApiClient::Base giving it ActiveRecord-like class methods
|
23
|
+
(find, find_all, create, update, destroy) as well as instance methods
|
24
|
+
(save, destroy).
|
25
|
+
|
26
|
+
## Making requests
|
27
|
+
|
28
|
+
By design, all request methods are singleton methods. They either return Ruby
|
29
|
+
objects or objects of the class they are called on.
|
30
|
+
|
31
|
+
### `ApiClient::Base.get(path, params = {})`
|
32
|
+
|
33
|
+
Make a GET request to a specified path. You can pass params as the second
|
34
|
+
argument. It will parse the representation and return a Ruby object.
|
35
|
+
|
36
|
+
#### Example
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
ApiClient::Base.get('/apples/1.json')
|
40
|
+
# => returns a parsed Hash
|
41
|
+
```
|
42
|
+
|
43
|
+
### `ApiClient::Base.post(path, params = {})`
|
44
|
+
|
45
|
+
Make a POST request to a specified path. You can pass params as the second
|
46
|
+
argument. It will parse the representation and return a Ruby object.
|
47
|
+
|
48
|
+
#### Example
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
ApiClient::Base.post('/apples/1.json', :name => 'Lobo')
|
52
|
+
# => returns a parsed Hash
|
53
|
+
```
|
54
|
+
|
55
|
+
### `ApiClient::Base.put(path, params = {})`
|
56
|
+
|
57
|
+
Make a PUT request to a specified path. You can pass params as the second
|
58
|
+
argument. It will parse the representation and return a Ruby object.
|
59
|
+
|
60
|
+
#### Example
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
ApiClient::Base.put('/apples/1.json', :name => 'Lobo')
|
64
|
+
# => returns a parsed Hash
|
65
|
+
```
|
66
|
+
|
67
|
+
### `ApiClient::Base.delete(path, params = {})`
|
68
|
+
|
69
|
+
Make a DELETE request to a specified path. You can pass params as the second
|
70
|
+
argument. It will parse the representation and return a Ruby object.
|
71
|
+
|
72
|
+
#### Example
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
ApiClient::Base.delete('/apples/1.json')
|
76
|
+
# => returns a parsed Hash
|
77
|
+
```
|
78
|
+
|
79
|
+
### `ApiClient::Base.fetch(path, params = {})`
|
80
|
+
|
81
|
+
Make a GET request to a specified path. You can pass params as the second
|
82
|
+
argument. It will parse the representation, pass it to the build method and
|
83
|
+
return and object of the class it was called on.
|
84
|
+
|
85
|
+
#### Example
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
ApiClient::Base.fetch('/apples/1.json')
|
89
|
+
# => returns a ApiClient::Base object
|
90
|
+
|
91
|
+
class Apple < ApiClient::Base
|
92
|
+
end
|
93
|
+
|
94
|
+
Apple.fetch('/apples/1.json')
|
95
|
+
# => returns an Apple object
|
96
|
+
```
|
97
|
+
|
98
|
+
## Scoping and Chaining
|
99
|
+
|
100
|
+
ApiClient allows you to apply scoping to your request using 3 methods:
|
101
|
+
|
102
|
+
* ApiClient::Base.params(pars = {})
|
103
|
+
|
104
|
+
This method allows you to add parameters to a request. If the request is a
|
105
|
+
GET request, it will be added in the query. Otherwise, it will be sent in
|
106
|
+
the request body.
|
107
|
+
|
108
|
+
It returns a ApiClient::Scope object attached to a class you started with.
|
109
|
+
|
110
|
+
* ApiClient::Base.options(opts = {})
|
111
|
+
|
112
|
+
Allows passing options to the connection object behind the ApiClient. Useful
|
113
|
+
when working with OAuth for passing the token.
|
114
|
+
|
115
|
+
It returns a ApiClient::Scope object attached to a class you started with.
|
116
|
+
|
117
|
+
* ApiClient::Base.headers(heads = {})
|
118
|
+
|
119
|
+
Allows setting headers in the request. Useful when you need to add a token
|
120
|
+
as the header
|
121
|
+
|
122
|
+
It returns a ApiClient::Scope object attached to a class you started with.
|
123
|
+
|
124
|
+
All of these methods return a ApiClient::Scope object. When you call any request
|
125
|
+
methods on this object (get, post, put, delete), the request will apply the
|
126
|
+
options, params and headers.
|
127
|
+
|
128
|
+
### Examples
|
129
|
+
|
130
|
+
#### Params, headers and a GET request
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
ApiClient::Base.
|
134
|
+
params({ :page => 1 }).
|
135
|
+
headers('Auth-Token', 'mytoken').
|
136
|
+
get('/stuff.json') # => returns a parsed Array object
|
137
|
+
```
|
138
|
+
|
10
139
|
Copyright
|
11
140
|
---------
|
12
141
|
|
data/lib/api_client/base.rb
CHANGED
@@ -43,7 +43,13 @@ module ApiClient
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def inspect
|
46
|
-
|
46
|
+
attributes = []
|
47
|
+
attr_keys = self.keys - ['id']
|
48
|
+
attributes.push "id: #{self.id}" if self.id
|
49
|
+
attr_keys.each do |key|
|
50
|
+
attributes.push("#{key}: #{self[key].inspect}")
|
51
|
+
end
|
52
|
+
"#<#{self.class} #{attributes.join(', ')}>"
|
47
53
|
end
|
48
54
|
|
49
55
|
end
|
data/lib/api_client/version.rb
CHANGED
@@ -10,8 +10,29 @@ describe ApiClient::Base do
|
|
10
10
|
subject.should respond_to("id")
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
|
14
|
+
describe "#inspect" do
|
15
|
+
|
16
|
+
it "has a nice inspect" do
|
17
|
+
subject.update(:id => 1).inspect.should == '#<ApiClient::Base id: 1>'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "presents all fields in inspect" do
|
21
|
+
subject.update(:id => 1, :foo => 'OMG')
|
22
|
+
subject.inspect.should == '#<ApiClient::Base id: 1, foo: "OMG">'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "inspects subobjects properly" do
|
26
|
+
subject.update(:id => 1, :sub => [1,2])
|
27
|
+
subject.inspect.should == '#<ApiClient::Base id: 1, sub: [1, 2]>'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "makes sure id is the first key" do
|
31
|
+
|
32
|
+
subject.update(:foo => 'OMG', :id => 1)
|
33
|
+
subject.inspect.should == '#<ApiClient::Base id: 1, foo: "OMG">'
|
34
|
+
end
|
35
|
+
|
15
36
|
end
|
16
37
|
|
17
|
-
end
|
38
|
+
end
|
@@ -34,13 +34,17 @@ describe ApiClient::Connection::Basic do
|
|
34
34
|
before do
|
35
35
|
@instance = ApiClient::Connection::Basic.new("http://google.com")
|
36
36
|
@headers = { "header" => "token" }
|
37
|
-
@params = {
|
37
|
+
@params = { "param" => "1", "nested" => { "param" => "1" } }
|
38
38
|
@response = Faraday::Response.new(:status => 200)
|
39
39
|
end
|
40
40
|
|
41
41
|
it "can perform GET requests" do
|
42
|
-
@instance.handler.should_receive(:get)
|
43
|
-
|
42
|
+
@instance.handler.should_receive(:get) do |path, headers|
|
43
|
+
headers.should == @headers
|
44
|
+
Faraday::Utils.parse_nested_query(path.split("?").last).should == @params
|
45
|
+
@response
|
46
|
+
end
|
47
|
+
@instance.get "/home", @params, @headers
|
44
48
|
end
|
45
49
|
|
46
50
|
it "can perform POST requests" do
|
@@ -54,7 +58,11 @@ describe ApiClient::Connection::Basic do
|
|
54
58
|
end
|
55
59
|
|
56
60
|
it "can perform DELETE requests" do
|
57
|
-
@instance.handler.should_receive(:delete)
|
61
|
+
@instance.handler.should_receive(:delete) do |path, headers|
|
62
|
+
headers.should == @headers
|
63
|
+
Faraday::Utils.parse_nested_query(path.split("?").last).should == @params
|
64
|
+
@response
|
65
|
+
end
|
58
66
|
@instance.delete "/home", @params, @headers
|
59
67
|
end
|
60
68
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 0.7.5
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.7.5
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: hashie
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: 1.2.0
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.2.0
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: yajl-ruby
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,7 +53,12 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
description: API client builder
|
48
63
|
email:
|
49
64
|
- marcin@futuresimple.com
|
@@ -122,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
137
|
version: '0'
|
123
138
|
requirements: []
|
124
139
|
rubyforge_project: api_client
|
125
|
-
rubygems_version: 1.8.
|
140
|
+
rubygems_version: 1.8.24
|
126
141
|
signing_key:
|
127
142
|
specification_version: 3
|
128
143
|
summary: API client builder
|
@@ -146,3 +161,4 @@ test_files:
|
|
146
161
|
- spec/spec_helper.rb
|
147
162
|
- spec/support/fake_logger.rb
|
148
163
|
- spec/support/matchers.rb
|
164
|
+
has_rdoc:
|