api-client 1.2.0 → 1.3.0

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/.rspec CHANGED
@@ -1 +1 @@
1
- --colour --format documentation
1
+ --colour --format documentation --profile
data/.travis.yml CHANGED
@@ -1,5 +1,2 @@
1
1
  rvm:
2
- - ree-1.8.7
3
- - 1.8.7
4
- - 1.9.2
5
2
  - 1.9.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,53 @@
1
+ # CHANGELOG
2
+
3
+ ## v1.2.0
4
+
5
+ * methods put, patch and delete added.
6
+ * changed post method to send as json by default, but left option to override it.
7
+ * header params added to methods.
8
+
9
+ ## v1.1.1
10
+
11
+ * fix for post when uri has a non default port (80).
12
+
13
+ ## v1.1.0
14
+
15
+ * changed post method to always send as json.
16
+
17
+ ## v1.0.0
18
+
19
+ * handler for response code 400 removed.
20
+ * Refactoring of usage.
21
+
22
+ ## v0.6.0
23
+
24
+ * handler for response code 400 added.
25
+
26
+ ## v0.5.0
27
+
28
+ * handler for connection refused added.
29
+
30
+ ## v0.4.1
31
+
32
+ * rename gem name to fix require issues.
33
+
34
+ ## v0.4.0
35
+
36
+ * handlers for response code 500, 502 and 503 added.
37
+
38
+ ## v0.3.0
39
+
40
+ * handler for response code 401 added.
41
+
42
+ ## v0.2.0
43
+
44
+ * post method added
45
+
46
+ ## v0.1.0
47
+
48
+ * generic exception added.
49
+
50
+ ## v0.0.1
51
+
52
+ * get method added.
53
+ * handler for response code 404 added.
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # ApiClient [![Build Status](https://secure.travis-ci.org/plribeiro3000/api-client.png)](http://travis-ci.org/plribeiro3000/api-client)
2
2
 
3
- Client to make Api calls
3
+ Client to make Api calls inside Rails easily. The master only supports ruby-1.9.3.
4
+ For older versions, check branch retro-compatibility.
4
5
 
5
6
  ## Installation
6
7
 
data/api-client.gemspec CHANGED
@@ -16,7 +16,8 @@ Gem::Specification.new do |gem|
16
16
 
17
17
  gem.add_development_dependency "rake"
18
18
  gem.add_development_dependency "fakeweb"
19
- gem.add_development_dependency "rspec", "2.9.0"
19
+ gem.add_development_dependency "rspec"
20
+ gem.add_development_dependency "yard"
20
21
 
21
22
  gem.add_runtime_dependency "activemodel"
22
23
  gem.add_runtime_dependency "json_pure"
data/lib/api-client.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "api-client/version"
2
2
 
3
+ # High Level Namespace of the library ApiClient.
3
4
  module ApiClient
4
5
  autoload :Exceptions, 'api-client/exceptions'
5
6
  autoload :Base, 'api-client/base'
@@ -1,5 +1,11 @@
1
1
  require "active_model"
2
2
 
3
+ # ApiClient::Base provides a way to make easy api requests as well as making possible to use it inside rails.
4
+ # A possible implementation:
5
+ # class Car < ApiClient::Base
6
+ # attr_accessor :color, :name, :year
7
+ # end
8
+ # This class will handle Rails form as well as it works with respond_with.
3
9
  class ApiClient::Base
4
10
  include ActiveModel::Validations
5
11
  include ActiveModel::Conversion
@@ -8,32 +14,102 @@ class ApiClient::Base
8
14
  extend ApiClient::Parser
9
15
  extend ApiClient::Dispatcher
10
16
 
17
+ # Initialize an object based on a hash of a attributes.
18
+ #
19
+ # @param [Hash] attributes object attributes.
20
+ # @return [Base] the object initialized.
11
21
  def initialize(attributes = {})
12
22
  attributes.each do |name, value|
13
23
  send("#{name}=", value)
14
24
  end
15
25
  end
16
26
 
27
+ # Return if a object is persisted on the database or not.
28
+ #
29
+ # @return [False] it will always return false.
17
30
  def persisted?
18
31
  false
19
32
  end
20
33
 
34
+ # Make a get request and returns a new instance with te response attributes.
35
+ #
36
+ # @param [String] url of the api request.
37
+ # @param [Hash] header attributes of the request.
38
+ # @return [Base] a new object initialized with the response.
39
+ # @raise [ApiClient::Exceptions::ConnectionRefused] The request was refused by the api.
40
+ # @raise [ApiClient::Exceptions::Unauthorized] The request requires user authentication.
41
+ # @raise [ApiClient::Exceptions::Forbidden] The request was refused.
42
+ # @raise [ApiClient::Exceptions::NotFound] The request uri has not be found.
43
+ # @raise [ApiClient::Exceptions::InternalServerError] The request was not fulfilled by the api.
44
+ # @raise [ApiClient::Exceptions::BadGateway] The request was not fulfilled by the api.
45
+ # @raise [ApiClient::Exceptions::ServiceUnavailable] The api was unable to handle the request.
21
46
  def self.get(url = '', header = {})
22
47
  dispatch { _get(url, header) }
23
48
  end
24
49
 
50
+ # Make a post request and returns a new instance with te response attributes.
51
+ #
52
+ # @param [String] url of the api request.
53
+ # @param [Hash] args attributes of object.
54
+ # @param [Hash] header attributes of the request.
55
+ # @return [Base] a new object initialized with the response.
56
+ # @raise [ApiClient::Exceptions::ConnectionRefused] The request was refused by the api.
57
+ # @raise [ApiClient::Exceptions::Unauthorized] The request requires user authentication.
58
+ # @raise [ApiClient::Exceptions::Forbidden] The request was refused.
59
+ # @raise [ApiClient::Exceptions::NotFound] The request uri has not be found.
60
+ # @raise [ApiClient::Exceptions::InternalServerError] The request was not fulfilled by the api.
61
+ # @raise [ApiClient::Exceptions::BadGateway] The request was not fulfilled by the api.
62
+ # @raise [ApiClient::Exceptions::ServiceUnavailable] The api was unable to handle the request.
25
63
  def self.post(url = '', args = {}, header = {})
26
64
  dispatch { _post(url, args, header) }
27
65
  end
28
66
 
67
+ # Make a put request and returns a new instance with te response attributes.
68
+ #
69
+ # @param [String] url of the api request.
70
+ # @param [Hash] args attributes of object.
71
+ # @param [Hash] header attributes of the request.
72
+ # @return [Base] a new object initialized with the response.
73
+ # @raise [ApiClient::Exceptions::ConnectionRefused] The request was refused by the api.
74
+ # @raise [ApiClient::Exceptions::Unauthorized] The request requires user authentication.
75
+ # @raise [ApiClient::Exceptions::Forbidden] The request was refused.
76
+ # @raise [ApiClient::Exceptions::NotFound] The request uri has not be found.
77
+ # @raise [ApiClient::Exceptions::InternalServerError] The request was not fulfilled by the api.
78
+ # @raise [ApiClient::Exceptions::BadGateway] The request was not fulfilled by the api.
79
+ # @raise [ApiClient::Exceptions::ServiceUnavailable] The api was unable to handle the request.
29
80
  def self.put(url = '', args = {}, header = {})
30
81
  dispatch { _put(url, args, header) }
31
82
  end
32
83
 
84
+ # Make a patch request and returns a new instance with te response attributes.
85
+ #
86
+ # @param [String] url of the api request.
87
+ # @param [Hash] args attributes of object.
88
+ # @param [Hash] header attributes of the request.
89
+ # @return [Base] a new object initialized with the response.
90
+ # @raise [ApiClient::Exceptions::ConnectionRefused] The request was refused by the api.
91
+ # @raise [ApiClient::Exceptions::Unauthorized] The request requires user authentication.
92
+ # @raise [ApiClient::Exceptions::Forbidden] The request was refused.
93
+ # @raise [ApiClient::Exceptions::NotFound] The request uri has not be found.
94
+ # @raise [ApiClient::Exceptions::InternalServerError] The request was not fulfilled by the api.
95
+ # @raise [ApiClient::Exceptions::BadGateway] The request was not fulfilled by the api.
96
+ # @raise [ApiClient::Exceptions::ServiceUnavailable] The api was unable to handle the request.
33
97
  def self.patch(url = '', args = {}, header = {})
34
98
  dispatch { _patch(url, args, header) }
35
99
  end
36
100
 
101
+ # Make a delete request and returns a new instance with te response attributes.
102
+ #
103
+ # @param [String] url of the api request.
104
+ # @param [Hash] header attributes of the request.
105
+ # @return [Base] a new object initialized with the response.
106
+ # @raise [ApiClient::Exceptions::ConnectionRefused] The request was refused by the api.
107
+ # @raise [ApiClient::Exceptions::Unauthorized] The request requires user authentication.
108
+ # @raise [ApiClient::Exceptions::Forbidden] The request was refused.
109
+ # @raise [ApiClient::Exceptions::NotFound] The request uri has not be found.
110
+ # @raise [ApiClient::Exceptions::InternalServerError] The request was not fulfilled by the api.
111
+ # @raise [ApiClient::Exceptions::BadGateway] The request was not fulfilled by the api.
112
+ # @raise [ApiClient::Exceptions::ServiceUnavailable] The api was unable to handle the request.
37
113
  def self.delete(url = '', header = {})
38
114
  dispatch { _delete(url, header) }
39
115
  end
@@ -42,12 +118,12 @@ class ApiClient::Base
42
118
 
43
119
  def self.dispatch
44
120
  begin
45
- code, body = _response(yield)
121
+ code, object = _response(yield)
46
122
  rescue Errno::ECONNREFUSED
47
123
  raise ApiClient::Exceptions::ConnectionRefused
48
124
  end
49
125
  raise_exception(code)
50
- new(body)
126
+ new(object)
51
127
  end
52
128
 
53
129
  def self.raise_exception(code)
@@ -1,26 +1,55 @@
1
1
  require "net/http"
2
2
 
3
+ # ApiClient::Dispatcher provides methods to make requests using the native ruby library 'net/http'
3
4
  module ApiClient::Dispatcher
5
+ # Make a get request and returns it.
6
+ #
7
+ # @param [String] url of the api request.
8
+ # @param [Hash] header attributes of the request.
9
+ # @return [HTTP] the response object.
4
10
  def _get(url, header)
5
11
  initialize_connection(url)
6
12
  @http.get(@uri.path, header)
7
13
  end
8
14
 
15
+ # Make a post request and returns it.
16
+ #
17
+ # @param [String] url of the api request.
18
+ # @param [Hash] args attributes of object.
19
+ # @param [Hash] header attributes of the request.
20
+ # @return [HTTP] the response object.
9
21
  def _post(url, args, header)
10
22
  initialize_connection(url)
11
23
  @http.post(@uri.path, args.to_json, { 'Content-Type' => 'application/json' }.merge(header))
12
24
  end
13
25
 
26
+ # Make a put request and returns it.
27
+ #
28
+ # @param [String] url of the api request.
29
+ # @param [Hash] args attributes of object.
30
+ # @param [Hash] header attributes of the request.
31
+ # @return [HTTP] the response object.
14
32
  def _put(url, args, header)
15
33
  initialize_connection(url)
16
34
  @http.put(@uri.path, args.to_json, { 'Content-Type' => 'application/json' }.merge(header))
17
35
  end
18
36
 
37
+ # Make a patch request and returns it.
38
+ #
39
+ # @param [String] url of the api request.
40
+ # @param [Hash] args attributes of object.
41
+ # @param [Hash] header attributes of the request.
42
+ # @return [HTTP] the response object.
19
43
  def _patch(url, args, header)
20
44
  initialize_connection(url)
21
45
  @http.patch(@uri.path, args.to_json, { 'Content-Type' => 'application/json' }.merge(header))
22
46
  end
23
47
 
48
+ # Make a delete request and returns it.
49
+ #
50
+ # @param [String] url of the api request.
51
+ # @param [Hash] header attributes of the request.
52
+ # @return [HTTP] the response object.
24
53
  def _delete(url, header)
25
54
  initialize_connection(url)
26
55
  @http.delete(@uri.path, header)
@@ -1,3 +1,4 @@
1
+ # Namespace for the ApiClient Exceptions.
1
2
  module ApiClient::Exceptions
2
3
  autoload :Generic, 'api-client/exceptions/generic'
3
4
  autoload :NotFound, 'api-client/exceptions/not_found'
@@ -1,4 +1,9 @@
1
+ # Exception for a Bad Gateway Response ( Status Code : 502 ).
2
+ # The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request.
1
3
  class ApiClient::Exceptions::BadGateway < ApiClient::Exceptions::Generic
4
+ # Initialize a new exception.
5
+ #
6
+ # @return [BadGateway] a new exception.
2
7
  def self.initialize
3
8
  super("Bad Gateway!")
4
9
  end
@@ -1,4 +1,8 @@
1
+ # Exception for a Connection Refused Response.
1
2
  class ApiClient::Exceptions::ConnectionRefused < ApiClient::Exceptions::Generic
3
+ # Initialize a new exception.
4
+ #
5
+ # @return [ConnectionRefused] a new exception.
2
6
  def self.initialize
3
7
  super("Connection Refused!")
4
8
  end
@@ -1,4 +1,9 @@
1
+ # Exception for a Forbidden Response ( Status Code : 403 ).
2
+ # The server understood the request, but is refusing to fulfill it.
1
3
  class ApiClient::Exceptions::Forbidden < ApiClient::Exceptions::Generic
4
+ # Initialize a new exception.
5
+ #
6
+ # @return [Forbidden] a new exception.
2
7
  def self.initialize
3
8
  super("Forbidden!")
4
9
  end
@@ -1,4 +1,10 @@
1
+ # All other exceptions should extend this one. This exception was made to
2
+ # be easy to handle all possible errors on api requests with just one line:
3
+ # rescue_from ApiClient::Exceptions::Generic, :with => :generic_error
1
4
  class ApiClient::Exceptions::Generic < StandardError
5
+ # Initialize a new exception.
6
+ #
7
+ # @return [Generic] a new exception.
2
8
  def self.initialize
3
9
  super("An Error Occurred!")
4
10
  end
@@ -1,4 +1,9 @@
1
+ # Exception for a Internal Server Error Response ( Status Code : 500 ).
2
+ # The server encountered an unexpected condition which prevented it from fulfilling the request.
1
3
  class ApiClient::Exceptions::InternalServerError < ApiClient::Exceptions::Generic
4
+ # Initialize a new exception.
5
+ #
6
+ # @return [InternalServerError] a new exception.
2
7
  def self.initialize
3
8
  super("Internal Server Errorr!")
4
9
  end
@@ -1,4 +1,9 @@
1
+ # Exception for a Not Found Response ( Status Code : 404 ).
2
+ # The server has not found anything matching the Request-URI.
1
3
  class ApiClient::Exceptions::NotFound < ApiClient::Exceptions::Generic
4
+ # Initialize a new exception.
5
+ #
6
+ # @return [NotFound] a new exception.
2
7
  def self.initialize
3
8
  super("The required url could not be found!")
4
9
  end
@@ -1,4 +1,9 @@
1
+ # Exception for a Service Unavailable Response ( Status Code : 503 ).
2
+ # The server is currently unable to handle the request due to a temporary overloading or maintenance of the server.
1
3
  class ApiClient::Exceptions::ServiceUnavailable < ApiClient::Exceptions::Generic
4
+ # Initialize a new exception.
5
+ #
6
+ # @return [ServiceUnavailable] a new exception.
2
7
  def self.initialize
3
8
  super("Service Unavailable!")
4
9
  end
@@ -1,4 +1,9 @@
1
+ # Exception for a Unauthorized Response ( Status Code : 401 ).
2
+ # The request requires user authentication.
1
3
  class ApiClient::Exceptions::Unauthorized < ApiClient::Exceptions::Generic
4
+ # Initialize a new exception.
5
+ #
6
+ # @return [Unauthorized] a new exception.
2
7
  def self.initialize
3
8
  super("Authentication Required!")
4
9
  end
@@ -1,10 +1,17 @@
1
+ # ApiClient::Parser provides a method to parse the request response.
1
2
  module ApiClient::Parser
3
+ # Parse the JSON response.
4
+ #
5
+ # @param [HTTP] response HTTP object for the request.
6
+ # @return [Array] the code and the body parsed.
2
7
  def _response(response)
3
8
  begin
4
9
  body = JSON.parse(response.body)
10
+ root_node = name.split('::').last.downcase
11
+ object = body.key?(root_node) ? body[root_node] : body
5
12
  rescue JSON::ParserError
6
- body = nil
13
+ object = nil
7
14
  end
8
- return response.code, body
15
+ return response.code, object
9
16
  end
10
17
  end
@@ -1,3 +1,5 @@
1
+ # High Level Namespace of the library ApiClient.
1
2
  module ApiClient
2
- VERSION = "1.2.0"
3
+ # Version of the library.
4
+ VERSION = "1.3.0"
3
5
  end
@@ -3,15 +3,30 @@ require 'spec_helper'
3
3
  describe ApiClient::Parser do
4
4
  describe "#_response" do
5
5
  context "with a valid json response" do
6
- before :each do
7
- FakeWeb.register_uri(:post, "http://api.example.com/user/5",
8
- :body => { :a => :b }.to_json,
9
- :status => "201")
10
- @response = ApiClient::Base._post('http://api.example.com/user/5', {}, {})
6
+ context "without a root node" do
7
+ before :each do
8
+ FakeWeb.register_uri(:post, "http://api.example.com/user/5",
9
+ :body => { :a => :b }.to_json,
10
+ :status => "201")
11
+ @response = ApiClient::Base._post('http://api.example.com/user/5', {}, {})
12
+ end
13
+
14
+ it "should return the response code and the body parsed" do
15
+ ApiClient::Base._response(@response).should == ['201', { "a" => "b" }]
16
+ end
11
17
  end
12
18
 
13
- it "should return the response code and the body parsed" do
14
- ApiClient::Base._response(@response).should == ['201', { "a" => "b" }]
19
+ context "with a root node" do
20
+ before :each do
21
+ FakeWeb.register_uri(:post, "http://api.example.com/user/5",
22
+ :body => { :base => { :a => :b } }.to_json,
23
+ :status => "201")
24
+ @response = ApiClient::Base._post('http://api.example.com/user/5', {}, {})
25
+ end
26
+
27
+ it "should return the response code and the body parsed" do
28
+ ApiClient::Base._response(@response).should == ['201', { "a" => "b" }]
29
+ end
15
30
  end
16
31
  end
17
32
 
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: 1.2.0
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-05 00:00:00.000000000 Z
12
+ date: 2012-07-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -48,17 +48,33 @@ dependencies:
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - '='
51
+ - - ! '>='
52
52
  - !ruby/object:Gem::Version
53
- version: 2.9.0
53
+ version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - '='
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yard
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
60
68
  - !ruby/object:Gem::Version
61
- version: 2.9.0
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
62
78
  - !ruby/object:Gem::Dependency
63
79
  name: activemodel
64
80
  requirement: !ruby/object:Gem::Requirement
@@ -101,6 +117,7 @@ files:
101
117
  - .rspec
102
118
  - .rvmrc
103
119
  - .travis.yml
120
+ - CHANGELOG.md
104
121
  - Gemfile
105
122
  - LICENSE
106
123
  - README.md
@@ -143,7 +160,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
160
  version: '0'
144
161
  segments:
145
162
  - 0
146
- hash: 2002336376780002209
163
+ hash: -2404782696775397333
147
164
  required_rubygems_version: !ruby/object:Gem::Requirement
148
165
  none: false
149
166
  requirements:
@@ -152,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
169
  version: '0'
153
170
  segments:
154
171
  - 0
155
- hash: 2002336376780002209
172
+ hash: -2404782696775397333
156
173
  requirements: []
157
174
  rubyforge_project:
158
175
  rubygems_version: 1.8.24
@@ -160,3 +177,4 @@ signing_key:
160
177
  specification_version: 3
161
178
  summary: Client to make Api calls
162
179
  test_files: []
180
+ has_rdoc: