flexirest 1.3.35 → 1.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +146 -75
- data/flexirest.gemspec +2 -1
- data/lib/flexirest/associations.rb +20 -0
- data/lib/flexirest/base.rb +1 -1
- data/lib/flexirest/configuration.rb +25 -0
- data/lib/flexirest/json_api_proxy.rb +398 -0
- data/lib/flexirest/lazy_association_loader.rb +9 -3
- data/lib/flexirest/proxy_base.rb +1 -1
- data/lib/flexirest/request.rb +30 -4
- data/lib/flexirest/version.rb +1 -1
- data/lib/flexirest.rb +1 -0
- data/spec/lib/json_api_spec.rb +392 -0
- data/spec/lib/request_spec.rb +3 -1
- metadata +5 -2
@@ -4,6 +4,7 @@ module Flexirest
|
|
4
4
|
module Configuration
|
5
5
|
module ClassMethods
|
6
6
|
@@base_url = nil
|
7
|
+
@@alias_type = nil
|
7
8
|
@@username = nil
|
8
9
|
@@password = nil
|
9
10
|
@@request_body_type = :form_encoded
|
@@ -92,6 +93,23 @@ module Flexirest
|
|
92
93
|
@@password = value
|
93
94
|
end
|
94
95
|
|
96
|
+
def alias_type(value = nil)
|
97
|
+
@alias_type ||= nil
|
98
|
+
if value.nil?
|
99
|
+
if @alias_type.nil?
|
100
|
+
if value.nil? && superclass.respond_to?(:alias_type)
|
101
|
+
superclass.alias_type
|
102
|
+
else
|
103
|
+
@@alias_type || nil
|
104
|
+
end
|
105
|
+
else
|
106
|
+
@alias_type
|
107
|
+
end
|
108
|
+
else
|
109
|
+
@alias_type = value
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
95
113
|
def request_body_type(value = nil)
|
96
114
|
@request_body_type ||= nil
|
97
115
|
if value.nil?
|
@@ -231,6 +249,13 @@ module Flexirest
|
|
231
249
|
def proxy(value = nil)
|
232
250
|
@proxy ||= nil
|
233
251
|
value ? @proxy = value : @proxy || nil
|
252
|
+
|
253
|
+
if !@proxy.nil?
|
254
|
+
return @proxy
|
255
|
+
elsif self.superclass.respond_to?(:proxy)
|
256
|
+
return self.superclass.proxy
|
257
|
+
end
|
258
|
+
nil
|
234
259
|
end
|
235
260
|
|
236
261
|
def _reset_configuration!
|
@@ -0,0 +1,398 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flexirest
|
4
|
+
# JSON API requests and responses
|
5
|
+
module JsonAPIProxy
|
6
|
+
@object ||= nil
|
7
|
+
@headers ||= {}
|
8
|
+
|
9
|
+
# Methods used across other modules
|
10
|
+
module Helpers
|
11
|
+
def singular?(word)
|
12
|
+
w = word.to_s
|
13
|
+
w.singularize == w && w.pluralize != w
|
14
|
+
end
|
15
|
+
|
16
|
+
def type(object)
|
17
|
+
# Retrieve the type value for JSON API from the Flexirest::Base class
|
18
|
+
# If `alias_type` has been defined within the class, use it
|
19
|
+
name = object.alias_type || object.class.alias_type
|
20
|
+
|
21
|
+
# If not, guess the type value from the class name itself
|
22
|
+
unless name
|
23
|
+
return object.class.name.underscore.split('/').last.pluralize
|
24
|
+
end
|
25
|
+
|
26
|
+
name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Creating JSON API requests
|
31
|
+
module Request
|
32
|
+
# Creating and formatting JSON API parameters
|
33
|
+
module Params
|
34
|
+
extend self
|
35
|
+
extend Flexirest::JsonAPIProxy::Helpers
|
36
|
+
|
37
|
+
def create(params, object)
|
38
|
+
# Create a parameters object with the resource's type value and id
|
39
|
+
parameters = Parameters.new(object.id, type(object))
|
40
|
+
|
41
|
+
# Remove id attribute from top-level hash, this will be included
|
42
|
+
# in the resource object
|
43
|
+
params.delete(:id)
|
44
|
+
|
45
|
+
# Build the JSON API compliant parameters
|
46
|
+
parameters.create_from_hash(params)
|
47
|
+
|
48
|
+
# Return the parameters as a hash, so it can be used elsewhere
|
49
|
+
parameters.to_hash
|
50
|
+
end
|
51
|
+
|
52
|
+
def translate(params, include_associations)
|
53
|
+
# Return to caller if nothing is to be done
|
54
|
+
return params unless params.present? && include_associations.present?
|
55
|
+
|
56
|
+
# Format the linked resources array, and assign to include key
|
57
|
+
params[:include] = format_include_params(include_associations)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def format_include_params(associations)
|
63
|
+
includes = []
|
64
|
+
|
65
|
+
associations.each do |key|
|
66
|
+
# Format each association name
|
67
|
+
# if the key is a nested hash, format each nested association too
|
68
|
+
# e.g. [author, comments.likes]
|
69
|
+
|
70
|
+
if key.is_a?(Hash)
|
71
|
+
# Create a link from each association to nested association
|
72
|
+
key.each { |k, val| val.each { |v| includes << "#{k}.#{v}" } }
|
73
|
+
|
74
|
+
else
|
75
|
+
# Just convert the association to string, in case it is a Symbol
|
76
|
+
includes << key.to_s
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Join the includes array with comma separator
|
81
|
+
includes.join(',')
|
82
|
+
end
|
83
|
+
|
84
|
+
# Private class for building JSON API compliant parameters
|
85
|
+
class Parameters
|
86
|
+
include Flexirest::JsonAPIProxy::Helpers
|
87
|
+
|
88
|
+
def initialize(id, type)
|
89
|
+
@params = build(id, type)
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_hash
|
93
|
+
@params
|
94
|
+
end
|
95
|
+
|
96
|
+
def create_from_hash(hash)
|
97
|
+
hash.each do |k, v|
|
98
|
+
# Build JSON API compliant parameters from each key and value
|
99
|
+
# in the standard-style parameters hash
|
100
|
+
|
101
|
+
if v.is_a?(Array)
|
102
|
+
# This is a one-to-many relationship
|
103
|
+
validate_relationships!(v)
|
104
|
+
|
105
|
+
# Add a relationship object for all related resources
|
106
|
+
v.each { |el| add_relationship(k, type(el), el.id) }
|
107
|
+
|
108
|
+
elsif v.is_a?(Flexirest::Base)
|
109
|
+
# This is a one-to-one relationship
|
110
|
+
add_relationship(k, type(v), v.id)
|
111
|
+
|
112
|
+
else
|
113
|
+
# This is a normal attribute
|
114
|
+
add_attribute(k, v)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def add_relationship(name, type, id)
|
120
|
+
# Use the `name` parameter to determine the type of relationship
|
121
|
+
|
122
|
+
if singular?(name)
|
123
|
+
# If `name` is a singular word (one-to-one relationship),
|
124
|
+
# add or overwrite the data object for the given `name`,
|
125
|
+
# containing a type and id value to the relationships object
|
126
|
+
@params[:data][:relationships][name] =
|
127
|
+
{ data: { type: type, id: id } }
|
128
|
+
|
129
|
+
elsif @params[:data][:relationships][name]
|
130
|
+
# If `name` is a plural word (one-to-many relationship),
|
131
|
+
# and the `name` object already exists in the relationships object,
|
132
|
+
# assume a nested data array exists, and add a new data object
|
133
|
+
# containing a type and id value to the data array
|
134
|
+
@params[:data][:relationships][name][:data] <<
|
135
|
+
{ type: type, id: id }
|
136
|
+
|
137
|
+
else
|
138
|
+
# If `name` is a plural word, but the `name` object does not exist,
|
139
|
+
# add a new `name` object containing a data array,
|
140
|
+
# which consists of exactly one data object with the type and id
|
141
|
+
@params[:data][:relationships][name] =
|
142
|
+
{ data: [{ type: type, id: id }] }
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def add_attribute(key, value)
|
147
|
+
# Add a resource attribute to the attributes object
|
148
|
+
# within the resource object
|
149
|
+
@params[:data][:attributes][key] = value
|
150
|
+
end
|
151
|
+
|
152
|
+
def build(id, type)
|
153
|
+
# Build the standard resource object
|
154
|
+
pp = {}
|
155
|
+
pp[:data] = {}
|
156
|
+
pp[:data][:id] = id if id
|
157
|
+
pp[:data][:type] = type
|
158
|
+
pp[:data][:attributes] = {}
|
159
|
+
pp[:data][:relationships] = {}
|
160
|
+
pp
|
161
|
+
end
|
162
|
+
|
163
|
+
def validate_relationships!(v)
|
164
|
+
# Should always contain the same class in entire relationships array
|
165
|
+
raise_params_error! if v.map(&:class).count > 1
|
166
|
+
end
|
167
|
+
|
168
|
+
def raise_params_error!
|
169
|
+
raise Exception.new("Cannot contain different instance types!")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Creating JSON API header
|
176
|
+
module Headers
|
177
|
+
extend self
|
178
|
+
def save(headers)
|
179
|
+
# Save headers used in a request for building lazy association
|
180
|
+
# loaders when parsing the response
|
181
|
+
@headers = headers
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Parsing JSON API responses
|
186
|
+
module Response
|
187
|
+
extend self
|
188
|
+
extend Flexirest::JsonAPIProxy::Helpers
|
189
|
+
|
190
|
+
def save_resource_class(object)
|
191
|
+
@resource_class = object.is_a?(Class) ? object : object.class
|
192
|
+
end
|
193
|
+
|
194
|
+
def parse(body, object)
|
195
|
+
# Save resource class for building lazy association loaders
|
196
|
+
save_resource_class(object)
|
197
|
+
|
198
|
+
# Retrieve the resource(s) object or array from the data object
|
199
|
+
records = body['data']
|
200
|
+
return records unless records.present?
|
201
|
+
|
202
|
+
# Convert the resource object to an array,
|
203
|
+
# because it is easier to work with an array than a single object
|
204
|
+
# Also keep track if record is singular or plural for the result later
|
205
|
+
is_singular_record = records.is_a?(Hash)
|
206
|
+
records = [records] if is_singular_record
|
207
|
+
|
208
|
+
# Retrieve all names of linked relationships
|
209
|
+
if records.first['relationships']
|
210
|
+
relationships = records.first['relationships'].keys
|
211
|
+
end
|
212
|
+
|
213
|
+
resource_type = records.first['type']
|
214
|
+
included = body['included']
|
215
|
+
|
216
|
+
# Parse the records, and retrieve all resources in a
|
217
|
+
# (nested) array of resources that is easy to work with in Flexirest
|
218
|
+
resources = records.map do |record|
|
219
|
+
fetch_attributes_and_relationships(
|
220
|
+
resource_type, record, included, relationships
|
221
|
+
)
|
222
|
+
end
|
223
|
+
|
224
|
+
# Depending on whether we got a resource object (hash) or array
|
225
|
+
# in the beginning, return to the caller with the same type
|
226
|
+
is_singular_record ? resources.first : resources
|
227
|
+
end
|
228
|
+
|
229
|
+
private
|
230
|
+
|
231
|
+
def fetch_attributes_and_relationships(base, record, included, rels)
|
232
|
+
rels = (rels || []) - [base]
|
233
|
+
rels_object = record['relationships']
|
234
|
+
|
235
|
+
rels.each do |rel_name|
|
236
|
+
# Determine from `rel_name` (relationship name) whether the
|
237
|
+
# linked resource is a singular or plural (one-to-one or
|
238
|
+
# one-to-many, respectively)
|
239
|
+
is_singular_rel = singular?(rel_name)
|
240
|
+
|
241
|
+
if is_singular_rel
|
242
|
+
# Fetch a linked resource from the relationships object
|
243
|
+
# and add it as an association attribute in the resource hash
|
244
|
+
record[rel_name], embedded = fetch_one_to_one(
|
245
|
+
rels_object, rel_name, included
|
246
|
+
)
|
247
|
+
|
248
|
+
else
|
249
|
+
# Fetch linked resources from the relationships object
|
250
|
+
# and add it as an array into the resource hash
|
251
|
+
record[rel_name], embedded = fetch_one_to_many(
|
252
|
+
rels_object, rel_name, included
|
253
|
+
)
|
254
|
+
end
|
255
|
+
|
256
|
+
# Do not try to fetch embedded results if the response is not
|
257
|
+
# a compound document. Instead, a LazyAssociationLoader should
|
258
|
+
# have been created and inserted into the record
|
259
|
+
next record unless embedded
|
260
|
+
|
261
|
+
# Recursively fetch the relationships and embedded nested resources
|
262
|
+
linked_resources = record[rel_name].map do |nested_record|
|
263
|
+
# Find the relationships object in the linked resource
|
264
|
+
# and find whether there are any nested linked resources
|
265
|
+
nested_rels_object = nested_record['relationships']
|
266
|
+
|
267
|
+
if nested_rels_object && nested_rels_object.keys.present?
|
268
|
+
# Fetch the linked resources and its attributes recursively
|
269
|
+
fetch_attributes_and_relationships(
|
270
|
+
record['type'], nested_record, included, nested_rels_object.keys
|
271
|
+
)
|
272
|
+
|
273
|
+
else
|
274
|
+
# If there are no nested linked resources, just fetch the
|
275
|
+
# resource attributes of the linked resource
|
276
|
+
fetch_and_delete_attributes(nested_record)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# Depending on if the resource is singular or plural, add it as
|
281
|
+
# the original type (array or hash) into the record hash
|
282
|
+
record[rel_name] =
|
283
|
+
if is_singular_rel
|
284
|
+
linked_resources.first
|
285
|
+
else
|
286
|
+
linked_resources
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# Add the record attributes to the record hash
|
291
|
+
fetch_and_delete_attributes(record)
|
292
|
+
record
|
293
|
+
end
|
294
|
+
|
295
|
+
def fetch_one_to_one(relationships, name, included)
|
296
|
+
# Parse the relationships object given the relationship name `name`,
|
297
|
+
# and look into the included object (in case of a compound document),
|
298
|
+
# to embed the linked resource into the response
|
299
|
+
|
300
|
+
if included.blank? || relationships[name]['data'].blank?
|
301
|
+
begin
|
302
|
+
# When the response is not a compound document (i.e. there is no
|
303
|
+
# includes object), build a LazyAssociationLoader for lazy loading
|
304
|
+
return build_lazy_loader(
|
305
|
+
name, relationships[name]['links']['related']
|
306
|
+
), false
|
307
|
+
rescue NoMethodError
|
308
|
+
# If the url for retrieving the linked resource is missing,
|
309
|
+
# we assume there is no linked resource available to fetch
|
310
|
+
# Default nulled linked resource is `nil`
|
311
|
+
return nil, false
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
# Retrieve the linked resource id and its pluralized type name
|
316
|
+
rel_id = relationships[name]['data']['id']
|
317
|
+
plural_name = name.pluralize
|
318
|
+
|
319
|
+
# Traverse through the included object, and find the included
|
320
|
+
# linked resource, based on the given id and pluralized type name
|
321
|
+
linked_resource = included.select do |i|
|
322
|
+
i['id'] == rel_id && i['type'] == plural_name
|
323
|
+
end
|
324
|
+
|
325
|
+
return linked_resource, true
|
326
|
+
end
|
327
|
+
|
328
|
+
def fetch_one_to_many(relationships, name, included)
|
329
|
+
# Parse the relationships object given the relationship name `name`,
|
330
|
+
# and look into the included object (in case of a compound document),
|
331
|
+
# to embed the linked resources into the response
|
332
|
+
|
333
|
+
if included.blank? || relationships[name]['data'].blank?
|
334
|
+
begin
|
335
|
+
# When the response is not a compound document (i.e. there is no
|
336
|
+
# includes object), build a LazyAssociationLoader for lazy loading
|
337
|
+
return build_lazy_loader(
|
338
|
+
name, relationships[name]['links']['related']
|
339
|
+
), false
|
340
|
+
rescue NoMethodError
|
341
|
+
# If the url for retrieving the linked resources is missing,
|
342
|
+
# we assume there are no linked resources available to fetch
|
343
|
+
# Default nulled linked resources is an empty array
|
344
|
+
return [], false
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
# Retrieve the linked resources ids
|
349
|
+
rel_ids = relationships[name]['data'].map { |r| r['id'] }
|
350
|
+
|
351
|
+
# Traverse through the included object, and find the included
|
352
|
+
# linked resources, based on the given ids and type name
|
353
|
+
linked_resources = included.select do |i|
|
354
|
+
rel_ids.include?(i['id']) && i['type'] == name
|
355
|
+
end
|
356
|
+
|
357
|
+
return linked_resources, true
|
358
|
+
end
|
359
|
+
|
360
|
+
def fetch_and_delete_attributes(record)
|
361
|
+
# Fetch attribute keys and values from the resource object
|
362
|
+
# and insert into result record hash
|
363
|
+
record['attributes'].each do |k, v|
|
364
|
+
record[k] = v
|
365
|
+
end
|
366
|
+
|
367
|
+
delete_keys(record)
|
368
|
+
record
|
369
|
+
end
|
370
|
+
|
371
|
+
def delete_keys(record)
|
372
|
+
# Delete the attribute keys and values from the original response hash
|
373
|
+
record.delete('type')
|
374
|
+
record.delete('links')
|
375
|
+
record.delete('attributes')
|
376
|
+
record.delete('relationships')
|
377
|
+
end
|
378
|
+
|
379
|
+
def build_lazy_loader(name, url)
|
380
|
+
# Create a new request, given the linked resource `name`,
|
381
|
+
# finding the association's class, and given the `url` to the linked
|
382
|
+
# resource
|
383
|
+
|
384
|
+
request = Flexirest::Request.new(
|
385
|
+
{ url: url, method: :get },
|
386
|
+
@resource_class._associations[name.to_sym].new
|
387
|
+
)
|
388
|
+
|
389
|
+
# Also add the previous request's header, which may contain
|
390
|
+
# crucial authentication headers (or so), to connect with the service
|
391
|
+
request.headers = @headers
|
392
|
+
request.url = request.forced_url = url
|
393
|
+
|
394
|
+
Flexirest::LazyAssociationLoader.new(name, url, request)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
@@ -51,14 +51,20 @@ module Flexirest
|
|
51
51
|
yield loader
|
52
52
|
end
|
53
53
|
elsif @subloaders.is_a? Hash
|
54
|
-
@subloaders.each do |key,value|
|
54
|
+
@subloaders.each do |key, value|
|
55
55
|
yield key, value
|
56
56
|
end
|
57
57
|
end
|
58
58
|
else
|
59
59
|
ensure_lazy_loaded
|
60
|
-
@object.
|
61
|
-
|
60
|
+
if @object.is_a? Flexirest::Base
|
61
|
+
@object.each do |key, value|
|
62
|
+
yield key, value
|
63
|
+
end
|
64
|
+
else
|
65
|
+
@object.each do |obj|
|
66
|
+
yield obj
|
67
|
+
end
|
62
68
|
end
|
63
69
|
end
|
64
70
|
end
|
data/lib/flexirest/proxy_base.rb
CHANGED
data/lib/flexirest/request.rb
CHANGED
@@ -7,6 +7,7 @@ module Flexirest
|
|
7
7
|
|
8
8
|
class Request
|
9
9
|
include AttributeParsing
|
10
|
+
include JsonAPIProxy
|
10
11
|
attr_accessor :post_params, :get_params, :url, :path, :headers, :method, :object, :body, :forced_url, :original_url
|
11
12
|
|
12
13
|
def initialize(method, object, params = {})
|
@@ -106,6 +107,8 @@ module Flexirest
|
|
106
107
|
def request_body_type
|
107
108
|
if @method[:options][:request_body_type]
|
108
109
|
@method[:options][:request_body_type]
|
110
|
+
elsif @object.nil?
|
111
|
+
nil
|
109
112
|
elsif object_is_class?
|
110
113
|
@object.request_body_type
|
111
114
|
else
|
@@ -180,7 +183,7 @@ module Flexirest
|
|
180
183
|
end
|
181
184
|
|
182
185
|
response = (
|
183
|
-
if proxy
|
186
|
+
if proxy && proxy.is_a?(Class)
|
184
187
|
proxy.handle(self) do |request|
|
185
188
|
request.do_request(etag)
|
186
189
|
end
|
@@ -228,6 +231,12 @@ module Flexirest
|
|
228
231
|
params = {id:params}
|
229
232
|
end
|
230
233
|
|
234
|
+
# Format includes parameter for jsonapi
|
235
|
+
if proxy == :json_api
|
236
|
+
JsonAPIProxy::Request::Params.translate(params, @object._include_associations)
|
237
|
+
@object._reset_include_associations!
|
238
|
+
end
|
239
|
+
|
231
240
|
if @method[:options][:defaults].respond_to?(:call)
|
232
241
|
default_params = @method[:options][:defaults].call(params)
|
233
242
|
else
|
@@ -323,7 +332,17 @@ module Flexirest
|
|
323
332
|
end
|
324
333
|
|
325
334
|
def prepare_request_body(params = nil)
|
326
|
-
if
|
335
|
+
if proxy == :json_api
|
336
|
+
if http_method == :get || http_method == :delete
|
337
|
+
@body = ""
|
338
|
+
else
|
339
|
+
headers["Content-Type"] ||= "application/vnd.api+json"
|
340
|
+
@body = JsonAPIProxy::Request::Params.create(params || @post_params || {}, @object).to_json
|
341
|
+
end
|
342
|
+
|
343
|
+
headers["Accept"] ||= "application/vnd.api+json"
|
344
|
+
JsonAPIProxy::Headers.save(headers)
|
345
|
+
elsif http_method == :get
|
327
346
|
@body = ""
|
328
347
|
elsif request_body_type == :form_encoded
|
329
348
|
@body ||= (params || @post_params || {}).to_query
|
@@ -475,7 +494,6 @@ module Flexirest
|
|
475
494
|
raise TimeoutException.new("Timed out getting #{response.url}")
|
476
495
|
end
|
477
496
|
end
|
478
|
-
|
479
497
|
result
|
480
498
|
end
|
481
499
|
|
@@ -600,6 +618,10 @@ module Flexirest
|
|
600
618
|
@response.response_headers['Content-Type'].nil? || @response.response_headers['Content-Type'].include?('json')
|
601
619
|
end
|
602
620
|
|
621
|
+
def is_json_api_response?
|
622
|
+
@response.response_headers['Content-Type'] && @response.response_headers['Content-Type'].include?('application/vnd.api+json')
|
623
|
+
end
|
624
|
+
|
603
625
|
def is_xml_response?
|
604
626
|
@response.response_headers['Content-Type'].include?('xml')
|
605
627
|
end
|
@@ -610,10 +632,14 @@ module Flexirest
|
|
610
632
|
elsif is_json_response?
|
611
633
|
begin
|
612
634
|
body = @response.body.blank? ? {} : MultiJson.load(@response.body)
|
613
|
-
rescue MultiJson::ParseError
|
635
|
+
rescue MultiJson::ParseError
|
614
636
|
raise ResponseParseException.new(status:@response.status, body:@response.body, headers:@response.headers)
|
615
637
|
end
|
616
638
|
|
639
|
+
if is_json_api_response?
|
640
|
+
body = JsonAPIProxy::Response.parse(body, @object)
|
641
|
+
end
|
642
|
+
|
617
643
|
if options[:ignore_root]
|
618
644
|
body = body[options[:ignore_root].to_s]
|
619
645
|
end
|
data/lib/flexirest/version.rb
CHANGED
data/lib/flexirest.rb
CHANGED
@@ -13,6 +13,7 @@ require "flexirest/result_iterator"
|
|
13
13
|
require "flexirest/headers_list"
|
14
14
|
require "flexirest/lazy_loader"
|
15
15
|
require "flexirest/lazy_association_loader"
|
16
|
+
require "flexirest/json_api_proxy"
|
16
17
|
require "flexirest/request"
|
17
18
|
require "flexirest/request_delegator"
|
18
19
|
require "flexirest/validation"
|