api-client 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: