restify 0.1.2.1.b38 → 0.1.2.1.b40

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YmE0MzA0MGE4NTMyYTQ4YzA1M2IzNjEyMjUzODBmMjlkZjI5ZDM5YQ==
4
+ MGI1NWFhZGEzMzc5YjJlMmM5NDRjMGY5NzNhMjliZjcwZWI5MjBmZA==
5
5
  data.tar.gz: !binary |-
6
- ZDZiNjMyNmE1N2M3ODI3ZTE5YzhhN2NiZWIwNGU5NDZiODZkMjhmNQ==
6
+ YTMxY2I3Mjg2ZjdhNjZiM2E2YWM1ZTgyMjFkODc3YzczZGRhNTg5Ng==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NmViYzlmNGVkMjQ4NTRkYTQyNDczOTY0ZmI0ZTdjNWU3YWEzODk2ZjQ3MmU1
10
- NmUwZmIzMzBlY2QyMjllNGQzODEwNmJkM2I5MGMzMmM3ODcxYzkxYTk1MWZm
11
- ODA4Y2I4ZGY2ODYwZTM2YWY2Zjk3NDlmZjlhMzA5YzA1MzE1YTU=
9
+ M2IzZGYwOGM5OWRiOTBlYWM0YjNlMDQxYzhkNzhiNGFhZTE2MDBmNDVhZDU2
10
+ ZmIyY2FjNGY4NGJlN2FmZmU0YmU5MmE0YTM5NjA4ZjMzYzFhODNhZjU2YzVi
11
+ YTA5MjE4ZGZkYTg1ODM4YWI3NjkwNTQ1ZDQzN2M5Y2E3ZmY4NWY=
12
12
  data.tar.gz: !binary |-
13
- MmMyNzljYTY3OGEzZjdhM2IyZDQwM2U1ZDg2ZDBkMTQ5M2VjZTBlNDhhNjk2
14
- MWVhODFiZDVjOTg4ZmI3YTg1NmYyMjY0OTM2ZjI0ODc5OWJmMDMxMmZhMWY0
15
- MjVhOWJiMzBkM2Q0ZjkxZGY1NmYyNWZkYjI4YzM4YWU3ZDJiZTM=
13
+ MjI4ZmUyNjk5NmVmY2MzMWU4MTE5ZDdhNTY3ZDY0YWI2YjBmMTAzYTQwNjA2
14
+ YWE1YjkzYThjYjk5Nzk2MWI4ODA3MGMyNDgzY2RmMmU1Y2NkZmIzODVlMGY3
15
+ MjVlMTgzZjQ3MjNlMzUwNTk2ZDFmMGY3NWZiNTMzMjAyOTY0NzE=
data/lib/restify.rb CHANGED
@@ -1,40 +1,34 @@
1
1
  require 'restify/version'
2
+
3
+ require 'hashie'
4
+ require 'obligation'
5
+ require 'multi_json'
2
6
  require 'addressable/uri'
3
7
  require 'addressable/template'
4
- require 'multi_json'
5
- require 'obligation'
6
- require 'hashie'
7
8
 
8
9
  #
9
10
  module Restify
10
- require 'restify/adapter'
11
- require 'restify/client'
12
- require 'restify/result'
11
+ require 'restify/http'
12
+ require 'restify/error'
13
13
  require 'restify/relations'
14
+
15
+ require 'restify/context'
16
+ require 'restify/contextual'
14
17
  require 'restify/collection'
15
- require 'restify/link'
18
+ require 'restify/resource'
16
19
  require 'restify/relation'
20
+
21
+ require 'restify/link'
17
22
  require 'restify/request'
18
- require 'restify/resource'
19
23
  require 'restify/response'
20
24
 
21
25
  class << self
22
- def new(url)
23
- Client.new(url).request(:GET, nil)
24
- end
25
-
26
- def adapter
27
- @adapter ||= Adapter::EM.new
26
+ def new(uri, opts = {})
27
+ Context.new(uri, http, nil, opts).request(:GET, uri)
28
28
  end
29
29
 
30
- def decode(response)
31
- decoder = decoders.find { |d| d.accept?(response) }
32
- if decoder
33
- decoder.decode(response)
34
- else
35
- UnsupportedFormatError.new \
36
- "Cannot decode `#{response.content_type}' response."
37
- end
30
+ def http
31
+ @http ||= HTTP.new
38
32
  end
39
33
  end
40
34
  end
@@ -68,6 +68,7 @@ module Restify
68
68
 
69
69
  writer.fulfill Response.new(
70
70
  request,
71
+ req.last_effective_url,
71
72
  req.response_header.status,
72
73
  req.response_header,
73
74
  req.response
@@ -1,23 +1,15 @@
1
1
  module Restify
2
2
  #
3
3
  class Collection < Array
4
- include Result
4
+ include Contextual
5
5
  include Relations
6
6
 
7
- def initialize(client, data = [], response = nil)
8
- super data
7
+ def initialize(context, data = [])
8
+ @context = context
9
9
 
10
- map! do |item|
11
- case item
12
- when Hash
13
- Resource.new client, item
14
- else
15
- item
16
- end
17
- end
10
+ super data
18
11
 
19
- @client = client
20
- @relations = response ? response.relations(client) : nil
12
+ map! {|item| @context.inherit_value(item) }
21
13
  end
22
14
  end
23
15
  end
@@ -0,0 +1,126 @@
1
+ module Restify
2
+ # A resource context.
3
+ #
4
+ # The resource context contains relations and the effective
5
+ # response URI. The context is used to resolve relative URI
6
+ # and follow links.
7
+ #
8
+ class Context
9
+ include Addressable
10
+ include Relations
11
+
12
+ # The response object.
13
+ #
14
+ # @return [Response] The response or nil.
15
+ #
16
+ attr_reader :response
17
+
18
+ # Effective context URI.
19
+ #
20
+ # @return [Addressable::URI] Effective context URI.
21
+ #
22
+ attr_reader :uri
23
+
24
+ def initialize(uri, http, response = nil, opts = {})
25
+ @uri = uri.is_a?(URI) ? uri : URI.parse(uri.to_s)
26
+ @http = http
27
+ @response = response
28
+ end
29
+
30
+ def relations
31
+ @relations ||= load_relations
32
+ end
33
+
34
+ def expand(uri)
35
+ case uri
36
+ when Addressable::Template
37
+ Addressable::Template.new self.uri.join(uri.pattern).to_s
38
+ else
39
+ self.uri.join uri
40
+ end
41
+ end
42
+
43
+ def follow
44
+ if follow_location
45
+ new_relation follow_location
46
+ else
47
+ raise RuntimeError.new 'Nothing to follow'
48
+ end
49
+ end
50
+
51
+ def request(method, uri, data = nil, opts = {})
52
+ request = @http.request(method, expand(uri), data, opts)
53
+ request.then do |response|
54
+ if response.success?
55
+ inherit(uri: response.uri, response: response)
56
+ .new_value(response.decoded_body)
57
+ else
58
+ Context.raise_response_error(response)
59
+ end
60
+ end
61
+ end
62
+
63
+ def inherit_value(value)
64
+ inherit.new_value value
65
+ end
66
+
67
+ def new_relation(uri)
68
+ Relation.new(self, uri.to_s, expand(uri))
69
+ end
70
+
71
+ def add_relation(name, uri)
72
+ @relations[name] = new_relation(uri)
73
+ end
74
+
75
+ def inherit(opts = {})
76
+ Context.new \
77
+ opts.fetch(:uri) { @uri },
78
+ opts.fetch(:http) { @http },
79
+ opts.fetch(:response) { nil }
80
+ end
81
+
82
+ def new_value(value)
83
+ case value
84
+ when Hash
85
+ Resource.new(self, value)
86
+ when Array
87
+ Collection.new(self, value)
88
+ else
89
+ value
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def follow_location
96
+ if @response
97
+ @response.headers['LOCATION'] || @response.headers['CONTENT-LOCATION']
98
+ end
99
+ end
100
+
101
+ def load_relations
102
+ response_links.each_with_object(Hashie::Mash.new) do |link, relations|
103
+ if (rel = link.metadata['rel'])
104
+ relations[rel] = new_relation link.uri
105
+ end
106
+ end
107
+ end
108
+
109
+ def response_links
110
+ @response ? @response.links : []
111
+ end
112
+
113
+ class << self
114
+ def raise_response_error(response)
115
+ case response.code
116
+ when 400...500
117
+ raise ClientError.new(response)
118
+ when 500...600
119
+ raise ServerError.new(response)
120
+ else
121
+ raise RuntimeError.new "Unknown response code: #{response.code}"
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,32 @@
1
+ module Restify
2
+ module Contextual
3
+ extend Forwardable
4
+
5
+ # @!method relations
6
+ #
7
+ # Return hash of all relations.
8
+ #
9
+ # @return [Hashie::Mash] Relations.
10
+ # @see Context#relations
11
+ #
12
+ delegate :relations => :@context
13
+
14
+ # @!method response
15
+ #
16
+ # Return response if available.
17
+ #
18
+ # @return [Response] Response object.
19
+ # @see Context#response
20
+ #
21
+ delegate :response => :@context
22
+
23
+ # @!method follow
24
+ #
25
+ # Follow a LOCATION or CONTEXT-LOCATION header.
26
+ #
27
+ # @return [Relation] Relation to follow resource.
28
+ # @see Context#follow
29
+ #
30
+ delegate :follow => :@context
31
+ end
32
+ end
@@ -0,0 +1,53 @@
1
+ module Restify
2
+ #
3
+ # A {ResponseError} is returned on a non-successful
4
+ # response from server. Usually it will either be a
5
+ # {ClientError} or a {ServerError}.
6
+ #
7
+ class ResponseError < StandardError
8
+ attr_reader :response
9
+
10
+ def initialize(response)
11
+ @response = response
12
+ super "#{response.message} (#{response.code}) for `#{response.uri}':\n" \
13
+ " #{errors.inspect}"
14
+ end
15
+
16
+ # Return response status.
17
+ #
18
+ # @return [Symbol] Response status.
19
+ # @see Response#status
20
+ #
21
+ def status
22
+ response.status
23
+ end
24
+
25
+ # Return response status code.
26
+ #
27
+ # @return [Fixnum] Response status code.
28
+ # @see Response#code
29
+ #
30
+ def code
31
+ response.code
32
+ end
33
+
34
+ # Return hash or array of errors if response included
35
+ # such a thing otherwise it returns nil.
36
+ #
37
+ def errors
38
+ if response.decoded_body
39
+ response.decoded_body['errors'] || response.decoded_body[:errors]
40
+ else
41
+ response.body
42
+ end
43
+ end
44
+ end
45
+
46
+ # A {ClientError} will be raised when a response has a
47
+ # 4XX status code.
48
+ class ClientError < ResponseError; end
49
+
50
+ # A {ServerError} will be raised when a response has a
51
+ # 5XX status code.
52
+ class ServerError < ResponseError; end
53
+ end
@@ -0,0 +1,34 @@
1
+ require 'restify/adapter'
2
+
3
+ module Restify
4
+
5
+ # @api private
6
+ #
7
+ class HTTP
8
+ # @api private
9
+ #
10
+ def initialize
11
+ @adapter = self.class.adapter
12
+ end
13
+
14
+ # @api private
15
+ #
16
+ # Request given path with given method.
17
+ #
18
+ # Returns an obligation that will return a collection or
19
+ # resource or fail with a response error depending on
20
+ # response from server.
21
+ #
22
+ def request(method, uri, data = nil, opts = {})
23
+ request = Request.new method: method, uri: uri, data: data
24
+
25
+ @adapter.call(request)
26
+ end
27
+
28
+ class << self
29
+ def adapter
30
+ @adapter ||= Restify::Adapter::EM.new
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/restify/link.rb CHANGED
@@ -5,9 +5,9 @@ module Restify
5
5
  #
6
6
  class Link
7
7
  #
8
- # URI of the link interpreted as a RFC6570 template.
8
+ # Extract URI string.
9
9
  #
10
- # @return [Addressable::Template] URI template.
10
+ # @return [String] URI string.
11
11
  #
12
12
  attr_reader :uri
13
13
 
@@ -56,7 +56,7 @@ module Restify
56
56
 
57
57
  def parse_link(scanner)
58
58
  if (m = scanner.scan(REGEXP_URI))
59
- uri = Addressable::Template.new(m.strip[1..-2])
59
+ uri = m.strip[1..-2]
60
60
  params = parse_params(scanner)
61
61
  new uri, params
62
62
  else
@@ -1,62 +1,54 @@
1
1
  module Restify
2
2
  #
3
3
  class Relation
4
- def initialize(client, uri_template)
5
- @client = client
6
- @template = if uri_template.is_a?(Addressable::Template)
7
- uri_template
8
- else
9
- Addressable::Template.new(uri_template)
10
- end
4
+ def initialize(context, source, pattern)
5
+ @context = context
6
+ @source = source
7
+ @template = to_template(pattern)
11
8
  end
12
9
 
13
10
  def get(params = {})
14
- request :get, params
11
+ request :get, nil, params
15
12
  end
16
13
 
17
14
  def delete(params = {})
18
- request :delete, params
15
+ request :delete, nil, params
19
16
  end
20
17
 
21
18
  def post(data = {}, params = {})
22
- request :post, params.merge(data: data)
19
+ request :post, data, params
23
20
  end
24
21
 
25
22
  def put(data = {}, params = {})
26
- request :put, params.merge(data: data)
23
+ request :put, data, params
27
24
  end
28
25
 
29
26
  def patch(data = {}, params = {})
30
- request :patch, params.merge(data: data)
27
+ request :patch, data, params
31
28
  end
32
29
 
33
30
  def ==(other)
34
- super || (other.is_a?(String) && @template.pattern == other)
31
+ super ||
32
+ (other.is_a?(String) && @template.pattern == other) ||
33
+ (other.is_a?(String) && @source == other)
35
34
  end
36
35
 
37
36
  private
38
37
 
39
38
  attr_reader :client, :template
40
39
 
41
- def request(method, opts = {})
42
- keys = template.variables - Client::RESERVED_KEYS
43
- params = extract_params(opts, keys)
44
- uri = template.expand(params)
40
+ def request(method, data, params)
41
+ uri = template.expand params
45
42
 
46
- client.request method, uri, opts
43
+ @context.request method, uri, data
47
44
  end
48
45
 
49
- def extract_params(opts, keys)
50
- params = {}
51
- keys.each do |key|
52
- if opts.key?(key)
53
- params[key] = opts.delete(key)
54
- elsif opts.key?(key.to_sym)
55
- params[key] = opts.delete(key.to_sym)
56
- end
46
+ def to_template(pattern)
47
+ if pattern.is_a?(Addressable::Template)
48
+ pattern
49
+ else
50
+ Addressable::Template.new pattern
57
51
  end
58
-
59
- params
60
52
  end
61
53
  end
62
54
  end
@@ -23,13 +23,5 @@ module Restify
23
23
  relations.fetch name
24
24
  end
25
25
  alias_method :relation, :rel
26
-
27
- # Hash of all known relations.
28
- #
29
- # @return [Hash<String, Relation>] Relations.
30
- #
31
- def relations
32
- @relations ||= Hashie::Mash.new
33
- end
34
26
  end
35
27
  end
@@ -25,7 +25,9 @@ module Restify
25
25
  end
26
26
 
27
27
  def body
28
- @body ||= MultiJson.dump(data)
28
+ @body ||= begin
29
+ MultiJson.dump(data) unless data.nil?
30
+ end
29
31
  end
30
32
 
31
33
  def headers
@@ -1,17 +1,14 @@
1
1
  module Restify
2
2
  #
3
3
  class Resource < Hashie::Hash
4
- include Result
4
+ include Contextual
5
5
  include Relations
6
6
  include Hashie::Extensions::IndifferentAccess
7
7
  include Hashie::Extensions::MethodReader
8
8
 
9
9
  #
10
- def initialize(client, data = {}, response = nil)
11
- @client = client
12
- @response = response
13
-
14
- relations.merge! @response.relations(client) if @response
10
+ def initialize(context, data = {})
11
+ @context = context
15
12
 
16
13
  data.each_pair do |key, value|
17
14
  self[key.to_s] = convert_value(value)
@@ -25,8 +22,8 @@ module Restify
25
22
  next
26
23
  end
27
24
 
28
- unless relations.key?(name) || value.nil? || value.to_s.empty?
29
- relations[name] = Relation.new(client, value.to_s)
25
+ unless @context.relation?(name) || value.nil? || value.to_s.empty?
26
+ @context.add_relation name, value.to_s
30
27
  end
31
28
  end
32
29
  end
@@ -53,12 +50,7 @@ module Restify
53
50
  # @private
54
51
  #
55
52
  def convert_value(value)
56
- case value
57
- when Hash
58
- self.new client, value
59
- else
60
- value
61
- end
53
+ @context.inherit_value(value)
62
54
  end
63
55
  end
64
56
  end
@@ -64,10 +64,17 @@ module Restify
64
64
  #
65
65
  attr_reader :request
66
66
 
67
+ # Last effective URI.
68
+ #
69
+ # @return [Addressable::URI] Last effective URI.
70
+ #
71
+ attr_reader :uri
72
+
67
73
  # @api private
68
74
  #
69
- def initialize(request, code, headers, body)
75
+ def initialize(request, uri, code, headers, body)
70
76
  @request = request
77
+ @uri = uri
71
78
  @code = code
72
79
  @status = STATUS_CODE_TO_SYMBOL[code]
73
80
  @headers = headers
@@ -75,12 +82,6 @@ module Restify
75
82
  @message = Rack::Utils::HTTP_STATUS_CODES[code]
76
83
  end
77
84
 
78
- # Return URL of this response.
79
- #
80
- def url
81
- request.uri
82
- end
83
-
84
85
  # Return list of links from the Link header.
85
86
  #
86
87
  # @return [Array<Link>] Links.
@@ -100,20 +101,6 @@ module Restify
100
101
  end
101
102
  end
102
103
 
103
- # Return list of relations extracted from links.
104
- #
105
- # @return [Array<Relation>] Relations.
106
- #
107
- def relations(client)
108
- relations = {}
109
- links.each do |link|
110
- if (rel = link.metadata['rel'])
111
- relations[rel] = Relation.new(client, link.uri)
112
- end
113
- end
114
- relations
115
- end
116
-
117
104
  # Return decoded body according to content type.
118
105
  # Will return `nil` if content cannot be decoded.
119
106
  #
@@ -8,7 +8,7 @@ describe Restify::Link do
8
8
  .parse('<http://example.org/search{?query}>; rel="search"')
9
9
 
10
10
  expect(links).to have(1).item
11
- expect(links[0].uri.pattern).to eq 'http://example.org/search{?query}'
11
+ expect(links[0].uri).to eq 'http://example.org/search{?query}'
12
12
  expect(links[0].metadata).to eq 'rel' => 'search'
13
13
  end
14
14
 
@@ -17,7 +17,7 @@ describe Restify::Link do
17
17
  .parse('<http://example.org/search{?query}>; rel=search')
18
18
 
19
19
  expect(links).to have(1).item
20
- expect(links[0].uri.pattern).to eq 'http://example.org/search{?query}'
20
+ expect(links[0].uri).to eq 'http://example.org/search{?query}'
21
21
  expect(links[0].metadata).to eq 'rel' => 'search'
22
22
  end
23
23
 
@@ -26,22 +26,22 @@ describe Restify::Link do
26
26
  .parse('<p://h.tld/p>; rel=abc, <p://h.tld/b>; a=b; c="d"')
27
27
 
28
28
  expect(links).to have(2).item
29
- expect(links[0].uri.pattern).to eq 'p://h.tld/p'
29
+ expect(links[0].uri).to eq 'p://h.tld/p'
30
30
  expect(links[0].metadata).to eq 'rel' => 'abc'
31
- expect(links[1].uri.pattern).to eq 'p://h.tld/b'
31
+ expect(links[1].uri).to eq 'p://h.tld/b'
32
32
  expect(links[1].metadata).to eq 'a' => 'b', 'c' => 'd'
33
33
  end
34
34
 
35
35
  it 'should parse link w/o meta' do
36
36
  links = described_class.parse('<p://h.tld/b>')
37
37
 
38
- expect(links[0].uri.pattern).to eq 'p://h.tld/b'
38
+ expect(links[0].uri).to eq 'p://h.tld/b'
39
39
  end
40
40
 
41
41
  it 'should parse on invalid URI' do
42
42
  links = described_class.parse('<hp://:&*^/fwbhg3>')
43
43
 
44
- expect(links[0].uri.pattern).to eq 'hp://:&*^/fwbhg3'
44
+ expect(links[0].uri).to eq 'hp://:&*^/fwbhg3'
45
45
  end
46
46
 
47
47
  it 'should error on invalid header' do
@@ -1,12 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Restify::Relation do
4
- let(:client) { double 'client' }
5
- let(:pattern) { 'http://test.host/resource/{id}' }
6
- let(:relation) { described_class.new client, pattern }
4
+ let(:context) { double 'context' }
5
+ let(:source) { '/resource/{id}' }
6
+ let(:pattern) { "http://test.host/#{source}" }
7
+ let(:relation) { described_class.new context, source, pattern }
7
8
  subject { relation }
8
9
 
9
10
  describe '#==' do
11
+ it 'should equal source' do
12
+ expect(subject).to eq source
13
+ end
14
+
10
15
  it 'should equal pattern' do
11
16
  expect(subject).to eq pattern
12
17
  end
@@ -1,9 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Restify::Resource do
4
- let(:client) { double 'client' }
5
4
  let(:data) { {} }
6
- let(:res) { described_class.new(client, data) }
5
+ let(:http) { double 'http' }
6
+ let(:context) { Restify::Context.new 'http://example.org', http }
7
+ let(:res) { described_class.new(context, data) }
7
8
 
8
9
  describe '#rel?' do
9
10
  let(:data) do
data/spec/restify_spec.rb CHANGED
@@ -144,17 +144,17 @@ describe Restify do
144
144
 
145
145
  # The server returns a 201 Created response with the created
146
146
  # resource.
147
- expect(created_user.status).to eq :created
148
- expect(created_user.code).to eq 201
147
+ expect(created_user.response.status).to eq :created
148
+ expect(created_user.response.code).to eq 201
149
149
 
150
150
  expect(created_user).to have_key :name
151
151
  expect(created_user.name).to eq 'John Smith'
152
152
 
153
153
  # Let's follow the "Location" header.
154
- followed_resource = created_user.follow.value
154
+ followed_resource = created_user.follow.get.value
155
155
 
156
- expect(followed_resource.status).to eq :ok
157
- expect(followed_resource.code).to eq 200
156
+ expect(followed_resource.response.status).to eq :ok
157
+ expect(followed_resource.response.code).to eq 200
158
158
 
159
159
  expect(followed_resource).to have_key :name
160
160
  expect(followed_resource.name).to eq 'John Smith'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.1.b38
4
+ version: 0.1.2.1.b40
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-13 00:00:00.000000000 Z
11
+ date: 2014-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: obligation
@@ -120,8 +120,11 @@ files:
120
120
  - README.md
121
121
  - lib/restify.rb
122
122
  - lib/restify/adapter.rb
123
- - lib/restify/client.rb
124
123
  - lib/restify/collection.rb
124
+ - lib/restify/context.rb
125
+ - lib/restify/contextual.rb
126
+ - lib/restify/error.rb
127
+ - lib/restify/http.rb
125
128
  - lib/restify/link.rb
126
129
  - lib/restify/parser/json.rb
127
130
  - lib/restify/relation.rb
@@ -129,7 +132,6 @@ files:
129
132
  - lib/restify/request.rb
130
133
  - lib/restify/resource.rb
131
134
  - lib/restify/response.rb
132
- - lib/restify/result.rb
133
135
  - lib/restify/version.rb
134
136
  - restify.gemspec
135
137
  - spec/restify/collection_spec.rb
@@ -1,110 +0,0 @@
1
- module Restify
2
- #
3
- # A {ResponseError} is returned on a non-successful
4
- # response from server. Usually it will either be a
5
- # {ClientError} or a {ServerError}.
6
- #
7
- class ResponseError < StandardError
8
- attr_reader :response
9
-
10
- def initialize(response)
11
- @response = response
12
- super "#{response.message} (#{response.code}) for `#{response.url}':\n" \
13
- " #{errors.inspect}"
14
- end
15
-
16
- # Return response status.
17
- #
18
- # @return [Symbol] Response status.
19
- # @see Response#status
20
- #
21
- def status
22
- response.status
23
- end
24
-
25
- # Return response status code.
26
- #
27
- # @return [Fixnum] Response status code.
28
- # @see Response#code
29
- #
30
- def code
31
- response.code
32
- end
33
-
34
- # Return hash or array of errors if response included
35
- # such a thing otherwise it returns nil.
36
- #
37
- def errors
38
- if response.decoded_body
39
- response.decoded_body['errors'] || response.decoded_body[:errors]
40
- else
41
- response.body
42
- end
43
- end
44
- end
45
-
46
- # A {ClientError} will be raised when a response has a
47
- # 4XX status code.
48
- class ClientError < ResponseError; end
49
-
50
- # A {ServerError} will be raised when a response has a
51
- # 5XX status code.
52
- class ServerError < ResponseError; end
53
-
54
- # @api private
55
- #
56
- class Client
57
- #
58
- # Keys that should not be extracted from options
59
- # to expand URI templates.
60
- RESERVED_KEYS = %w(data)
61
-
62
- # @api private
63
- #
64
- # Request given path with given method.
65
- #
66
- # Returns an obligation that will return a collection or
67
- # resource or fail with a response error depending on
68
- # response from server.
69
- #
70
- def request(method, path, opts = {})
71
- data = opts.fetch(:data, opts)
72
- request = Request.new method: method, uri: base.join(path.to_s), data: data
73
-
74
- ::Restify.adapter.call(request).then do |response|
75
- if response.success?
76
- handle_success response
77
- else
78
- handle_error response
79
- end
80
- end
81
- end
82
-
83
- private
84
-
85
- attr_reader :base
86
-
87
- def initialize(uri)
88
- @base = ::Addressable::URI.parse(uri)
89
- end
90
-
91
- def handle_success(response)
92
- if response.decoded_body.is_a?(Array)
93
- Collection.new(self, response.decoded_body, response)
94
- else
95
- Resource.new(self, response.decoded_body, response)
96
- end
97
- end
98
-
99
- def handle_error(response)
100
- case response.code
101
- when 400...500
102
- raise ClientError.new(response)
103
- when 500...600
104
- raise ServerError.new(response)
105
- else
106
- raise RuntimeError.new "Unknown response code: #{response.code}"
107
- end
108
- end
109
- end
110
- end
@@ -1,34 +0,0 @@
1
- module Restify
2
- module Result
3
- # Return response status if available.
4
- #
5
- # @return [Symbol] Response status.
6
- # @see Response#status
7
- #
8
- def status
9
- @response ? @response.status : nil
10
- end
11
-
12
- # Return response status code if available.
13
- #
14
- # @return [Fixnum] Response status code.
15
- # @see Response#code
16
- #
17
- def code
18
- @response ? @response.code : nil
19
- end
20
-
21
- # Follow the Location header from the response of
22
- # this resource if available.
23
- #
24
- # @return [Obligation<Resource>] Followed resource.
25
- #
26
- def follow
27
- if @response && @response.headers['LOCATION']
28
- @client.request :get, @response.headers['LOCATION']
29
- else
30
- raise RuntimeError.new 'Nothing to follow.'
31
- end
32
- end
33
- end
34
- end