restify 0.1.2.1.b38 → 0.1.2.1.b40

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.
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