api_client 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
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
 
@@ -43,7 +43,13 @@ module ApiClient
43
43
  end
44
44
 
45
45
  def inspect
46
- "#<#{self.class} id: #{self.id}>"
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
@@ -1,3 +1,3 @@
1
1
  module ApiClient
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
@@ -10,8 +10,29 @@ describe ApiClient::Base do
10
10
  subject.should respond_to("id")
11
11
  end
12
12
 
13
- it "has a nice inspect" do
14
- subject.update(:id => 1).inspect.should == '#<ApiClient::Base id: 1>'
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 = { :param => 1, :nested => { :param => 1 } }
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).with("/home?param=1&nested[param]=1", @headers).and_return(@response)
43
- @instance.get "/home", { :param => 1, :nested => { :param => 1 } }, @headers
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).with("/home?param=1&nested[param]=1", @headers).and_return(@response)
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.7
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-02-12 00:00:00.000000000 Z
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: &70245016564260 !ruby/object:Gem::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: *70245016564260
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: &70245016562640 !ruby/object:Gem::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: *70245016562640
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: &70245016423980 !ruby/object:Gem::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: *70245016423980
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.16
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: