jsonapi-resources 0.10.6 → 0.11.0.beta2
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/LICENSE.txt +1 -1
- data/README.md +39 -2
- data/lib/generators/jsonapi/controller_generator.rb +2 -0
- data/lib/generators/jsonapi/resource_generator.rb +2 -0
- data/lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb +3 -2
- data/lib/jsonapi/active_relation/join_manager.rb +30 -18
- data/lib/jsonapi/active_relation/join_manager_v10.rb +305 -0
- data/lib/jsonapi/active_relation_retrieval.rb +885 -0
- data/lib/jsonapi/active_relation_retrieval_v09.rb +715 -0
- data/lib/jsonapi/{active_relation_resource.rb → active_relation_retrieval_v10.rb} +113 -135
- data/lib/jsonapi/acts_as_resource_controller.rb +49 -49
- data/lib/jsonapi/cached_response_fragment.rb +4 -2
- data/lib/jsonapi/callbacks.rb +2 -0
- data/lib/jsonapi/compiled_json.rb +2 -0
- data/lib/jsonapi/configuration.rb +35 -15
- data/lib/jsonapi/error.rb +2 -0
- data/lib/jsonapi/error_codes.rb +2 -0
- data/lib/jsonapi/exceptions.rb +2 -0
- data/lib/jsonapi/formatter.rb +2 -0
- data/lib/jsonapi/include_directives.rb +77 -19
- data/lib/jsonapi/link_builder.rb +2 -0
- data/lib/jsonapi/mime_types.rb +6 -10
- data/lib/jsonapi/naive_cache.rb +2 -0
- data/lib/jsonapi/operation.rb +2 -0
- data/lib/jsonapi/operation_result.rb +2 -0
- data/lib/jsonapi/paginator.rb +2 -0
- data/lib/jsonapi/path.rb +2 -0
- data/lib/jsonapi/path_segment.rb +4 -2
- data/lib/jsonapi/processor.rb +95 -140
- data/lib/jsonapi/relationship.rb +89 -35
- data/lib/jsonapi/{request_parser.rb → request.rb} +157 -164
- data/lib/jsonapi/resource.rb +7 -2
- data/lib/jsonapi/{basic_resource.rb → resource_common.rb} +187 -88
- data/lib/jsonapi/resource_controller.rb +2 -0
- data/lib/jsonapi/resource_controller_metal.rb +2 -0
- data/lib/jsonapi/resource_fragment.rb +17 -15
- data/lib/jsonapi/resource_identity.rb +6 -0
- data/lib/jsonapi/resource_serializer.rb +20 -4
- data/lib/jsonapi/resource_set.rb +36 -16
- data/lib/jsonapi/resource_tree.rb +191 -0
- data/lib/jsonapi/resources/railtie.rb +3 -1
- data/lib/jsonapi/resources/version.rb +3 -1
- data/lib/jsonapi/response_document.rb +4 -2
- data/lib/jsonapi/routing_ext.rb +4 -2
- data/lib/jsonapi/simple_resource.rb +13 -0
- data/lib/jsonapi-resources.rb +10 -4
- data/lib/tasks/check_upgrade.rake +3 -1
- metadata +47 -15
- data/lib/jsonapi/resource_id_tree.rb +0 -112
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module JSONAPI
|
2
|
-
class
|
4
|
+
class Request
|
3
5
|
attr_accessor :fields, :include, :filters, :sort_criteria, :errors, :controller_module_path,
|
4
6
|
:context, :paginator, :source_klass, :source_id,
|
5
|
-
:include_directives, :params, :warnings, :server_error_callbacks
|
7
|
+
:include_directives, :params, :warnings, :server_error_callbacks, :operations
|
6
8
|
|
7
9
|
def initialize(params = nil, options = {})
|
8
10
|
@params = params
|
@@ -18,33 +20,25 @@ module JSONAPI
|
|
18
20
|
@errors = []
|
19
21
|
@warnings = []
|
20
22
|
@server_error_callbacks = options.fetch(:server_error_callbacks, [])
|
23
|
+
@operations = []
|
24
|
+
|
25
|
+
setup_operations(params)
|
21
26
|
end
|
22
27
|
|
23
28
|
def error_object_overrides
|
24
29
|
{}
|
25
30
|
end
|
26
31
|
|
27
|
-
def each(_response_document)
|
28
|
-
operation = setup_base_op(params)
|
29
|
-
if @errors.any?
|
30
|
-
fail JSONAPI::Exceptions::Errors.new(@errors)
|
31
|
-
else
|
32
|
-
yield operation
|
33
|
-
end
|
34
|
-
rescue ActionController::ParameterMissing => e
|
35
|
-
fail JSONAPI::Exceptions::ParameterMissing.new(e.param, error_object_overrides)
|
36
|
-
end
|
37
|
-
|
38
32
|
def transactional?
|
39
33
|
case params[:action]
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
when 'index', 'show_related_resource', 'index_related_resources', 'show', 'show_relationship'
|
35
|
+
false
|
36
|
+
else
|
37
|
+
true
|
44
38
|
end
|
45
39
|
end
|
46
40
|
|
47
|
-
def
|
41
|
+
def setup_operations(params)
|
48
42
|
return if params.nil?
|
49
43
|
|
50
44
|
resource_klass = Resource.resource_klass_for(params[:controller]) if params[:controller]
|
@@ -68,15 +62,15 @@ module JSONAPI
|
|
68
62
|
sort_criteria = parse_sort_criteria(resource_klass, params[:sort])
|
69
63
|
paginator = parse_pagination(resource_klass, params[:page])
|
70
64
|
|
71
|
-
JSONAPI::Operation.new(
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
65
|
+
@operations << JSONAPI::Operation.new(
|
66
|
+
:find,
|
67
|
+
resource_klass,
|
68
|
+
context: context,
|
69
|
+
filters: filters,
|
70
|
+
include_directives: include_directives,
|
71
|
+
sort_criteria: sort_criteria,
|
72
|
+
paginator: paginator,
|
73
|
+
fields: fields
|
80
74
|
)
|
81
75
|
end
|
82
76
|
|
@@ -90,15 +84,15 @@ module JSONAPI
|
|
90
84
|
|
91
85
|
relationship_type = params[:relationship].to_sym
|
92
86
|
|
93
|
-
JSONAPI::Operation.new(
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
87
|
+
@operations << JSONAPI::Operation.new(
|
88
|
+
:show_related_resource,
|
89
|
+
resource_klass,
|
90
|
+
context: @context,
|
91
|
+
relationship_type: relationship_type,
|
92
|
+
source_klass: source_klass,
|
93
|
+
source_id: source_id,
|
94
|
+
fields: fields,
|
95
|
+
include_directives: include_directives
|
102
96
|
)
|
103
97
|
end
|
104
98
|
|
@@ -114,18 +108,18 @@ module JSONAPI
|
|
114
108
|
paginator = parse_pagination(resource_klass, params[:page])
|
115
109
|
relationship_type = params[:relationship]
|
116
110
|
|
117
|
-
JSONAPI::Operation.new(
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
111
|
+
@operations << JSONAPI::Operation.new(
|
112
|
+
:show_related_resources,
|
113
|
+
resource_klass,
|
114
|
+
context: @context,
|
115
|
+
relationship_type: relationship_type,
|
116
|
+
source_klass: source_klass,
|
117
|
+
source_id: source_id,
|
118
|
+
filters: filters,
|
119
|
+
sort_criteria: sort_criteria,
|
120
|
+
paginator: paginator,
|
121
|
+
fields: fields,
|
122
|
+
include_directives: include_directives
|
129
123
|
)
|
130
124
|
end
|
131
125
|
|
@@ -135,14 +129,14 @@ module JSONAPI
|
|
135
129
|
include_directives = parse_include_directives(resource_klass, params[:include])
|
136
130
|
id = params[:id]
|
137
131
|
|
138
|
-
JSONAPI::Operation.new(
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
132
|
+
@operations << JSONAPI::Operation.new(
|
133
|
+
:show,
|
134
|
+
resource_klass,
|
135
|
+
context: @context,
|
136
|
+
id: id,
|
137
|
+
include_directives: include_directives,
|
138
|
+
fields: fields,
|
139
|
+
allowed_resources: params[:allowed_resources]
|
146
140
|
)
|
147
141
|
end
|
148
142
|
|
@@ -155,17 +149,17 @@ module JSONAPI
|
|
155
149
|
sort_criteria = parse_sort_criteria(resource_klass, params[:sort])
|
156
150
|
paginator = parse_pagination(resource_klass, params[:page])
|
157
151
|
|
158
|
-
JSONAPI::Operation.new(
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
152
|
+
@operations << JSONAPI::Operation.new(
|
153
|
+
:show_relationship,
|
154
|
+
resource_klass,
|
155
|
+
context: @context,
|
156
|
+
relationship_type: relationship_type,
|
157
|
+
parent_key: resource_klass.verify_key(parent_key),
|
158
|
+
filters: filters,
|
159
|
+
sort_criteria: sort_criteria,
|
160
|
+
paginator: paginator,
|
161
|
+
fields: fields,
|
162
|
+
include_directives: include_directives
|
169
163
|
)
|
170
164
|
end
|
171
165
|
|
@@ -183,14 +177,14 @@ module JSONAPI
|
|
183
177
|
|
184
178
|
data = parse_params(resource_klass, data, resource_klass.creatable_fields(@context))
|
185
179
|
|
186
|
-
JSONAPI::Operation.new(
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
180
|
+
@operations << JSONAPI::Operation.new(
|
181
|
+
:create_resource,
|
182
|
+
resource_klass,
|
183
|
+
context: @context,
|
184
|
+
data: data,
|
185
|
+
fields: fields,
|
186
|
+
include_directives: include_directives,
|
187
|
+
warnings: @warnings
|
194
188
|
)
|
195
189
|
end
|
196
190
|
|
@@ -225,25 +219,25 @@ module JSONAPI
|
|
225
219
|
|
226
220
|
verify_type(data[:type], resource_klass)
|
227
221
|
|
228
|
-
JSONAPI::Operation.new(
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
222
|
+
@operations << JSONAPI::Operation.new(
|
223
|
+
:replace_fields,
|
224
|
+
resource_klass,
|
225
|
+
context: @context,
|
226
|
+
resource_id: resource_id,
|
227
|
+
data: parse_params(resource_klass, data, resource_klass.updatable_fields(@context)),
|
228
|
+
fields: fields,
|
229
|
+
include_directives: include_directives,
|
230
|
+
warnings: @warnings
|
237
231
|
)
|
238
232
|
end
|
239
233
|
|
240
234
|
def setup_destroy_action(params, resource_klass)
|
241
235
|
resolve_singleton_id(params, resource_klass)
|
242
|
-
JSONAPI::Operation.new(
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
236
|
+
@operations << JSONAPI::Operation.new(
|
237
|
+
:remove_resource,
|
238
|
+
resource_klass,
|
239
|
+
context: @context,
|
240
|
+
resource_id: resource_klass.verify_key(params.require(:id), @context))
|
247
241
|
end
|
248
242
|
|
249
243
|
def setup_destroy_relationship_action(params, resource_klass)
|
@@ -349,7 +343,6 @@ module JSONAPI
|
|
349
343
|
else
|
350
344
|
fail JSONAPI::Exceptions::InvalidInclude.new(format_key(resource_klass._type), include_parts.first)
|
351
345
|
end
|
352
|
-
true
|
353
346
|
end
|
354
347
|
|
355
348
|
def parse_include_directives(resource_klass, raw_include)
|
@@ -458,19 +451,19 @@ module JSONAPI
|
|
458
451
|
def parse_to_one_links_object(raw)
|
459
452
|
if raw.nil?
|
460
453
|
return {
|
461
|
-
|
462
|
-
|
454
|
+
type: nil,
|
455
|
+
id: nil
|
463
456
|
}
|
464
457
|
end
|
465
458
|
|
466
459
|
if !(raw.is_a?(Hash) || raw.is_a?(ActionController::Parameters)) ||
|
467
|
-
|
460
|
+
raw.keys.length != 2 || !(raw.key?('type') && raw.key?('id'))
|
468
461
|
fail JSONAPI::Exceptions::InvalidLinksObject.new(error_object_overrides)
|
469
462
|
end
|
470
463
|
|
471
464
|
{
|
472
|
-
|
473
|
-
|
465
|
+
type: unformat_key(raw['type']).to_s,
|
466
|
+
id: raw['id']
|
474
467
|
}
|
475
468
|
end
|
476
469
|
|
@@ -499,33 +492,33 @@ module JSONAPI
|
|
499
492
|
|
500
493
|
params.each do |key, value|
|
501
494
|
case key.to_s
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
end
|
495
|
+
when 'relationships'
|
496
|
+
value.each do |link_key, link_value|
|
497
|
+
param = unformat_key(link_key)
|
498
|
+
relationship = resource_klass._relationship(param)
|
499
|
+
|
500
|
+
if relationship.is_a?(JSONAPI::Relationship::ToOne)
|
501
|
+
checked_to_one_relationships[param] = parse_to_one_relationship(resource_klass, link_value, relationship)
|
502
|
+
elsif relationship.is_a?(JSONAPI::Relationship::ToMany)
|
503
|
+
parse_to_many_relationship(resource_klass, link_value, relationship) do |result_val|
|
504
|
+
checked_to_many_relationships[param] = result_val
|
513
505
|
end
|
514
506
|
end
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
507
|
+
end
|
508
|
+
when 'id'
|
509
|
+
checked_attributes['id'] = unformat_value(resource_klass, :id, value)
|
510
|
+
when 'attributes'
|
511
|
+
value.each do |key, value|
|
512
|
+
param = unformat_key(key)
|
513
|
+
checked_attributes[param] = unformat_value(resource_klass, param, value)
|
514
|
+
end
|
522
515
|
end
|
523
516
|
end
|
524
517
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
518
|
+
{
|
519
|
+
'attributes' => checked_attributes,
|
520
|
+
'to_one' => checked_to_one_relationships,
|
521
|
+
'to_many' => checked_to_many_relationships
|
529
522
|
}.deep_transform_keys { |key| unformat_key(key) }
|
530
523
|
end
|
531
524
|
|
@@ -584,7 +577,7 @@ module JSONAPI
|
|
584
577
|
end
|
585
578
|
|
586
579
|
relationship_ids = relationship_resource_klass.verify_keys(keys, @context)
|
587
|
-
|
580
|
+
polymorphic_results << { type: type, ids: relationship_ids }
|
588
581
|
end
|
589
582
|
|
590
583
|
add_result.call polymorphic_results
|
@@ -612,45 +605,45 @@ module JSONAPI
|
|
612
605
|
|
613
606
|
params.each do |key, value|
|
614
607
|
case key.to_s
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
end
|
624
|
-
end
|
625
|
-
end
|
626
|
-
when 'attributes'
|
627
|
-
value.each do |attr_key, _attr_value|
|
628
|
-
unless formatted_allowed_fields.include?(attr_key.to_sym)
|
629
|
-
if JSONAPI.configuration.raise_if_parameters_not_allowed
|
630
|
-
fail JSONAPI::Exceptions::ParameterNotAllowed.new(attr_key, error_object_overrides)
|
631
|
-
else
|
632
|
-
params_not_allowed.push(attr_key)
|
633
|
-
value.delete attr_key
|
634
|
-
end
|
608
|
+
when 'relationships'
|
609
|
+
value.keys.each do |links_key|
|
610
|
+
unless formatted_allowed_fields.include?(links_key.to_sym)
|
611
|
+
if JSONAPI.configuration.raise_if_parameters_not_allowed
|
612
|
+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(links_key, error_object_overrides)
|
613
|
+
else
|
614
|
+
params_not_allowed.push(links_key)
|
615
|
+
value.delete links_key
|
635
616
|
end
|
636
617
|
end
|
637
|
-
|
638
|
-
|
639
|
-
|
618
|
+
end
|
619
|
+
when 'attributes'
|
620
|
+
value.each do |attr_key, _attr_value|
|
621
|
+
unless formatted_allowed_fields.include?(attr_key.to_sym)
|
640
622
|
if JSONAPI.configuration.raise_if_parameters_not_allowed
|
641
|
-
fail JSONAPI::Exceptions::ParameterNotAllowed.new(
|
623
|
+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(attr_key, error_object_overrides)
|
642
624
|
else
|
643
|
-
params_not_allowed.push(
|
644
|
-
|
625
|
+
params_not_allowed.push(attr_key)
|
626
|
+
value.delete attr_key
|
645
627
|
end
|
646
628
|
end
|
647
|
-
|
629
|
+
end
|
630
|
+
when 'type'
|
631
|
+
when 'id'
|
632
|
+
unless formatted_allowed_fields.include?(:id)
|
648
633
|
if JSONAPI.configuration.raise_if_parameters_not_allowed
|
649
|
-
fail JSONAPI::Exceptions::ParameterNotAllowed.new(
|
634
|
+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(:id, error_object_overrides)
|
650
635
|
else
|
651
|
-
params_not_allowed.push(
|
652
|
-
params.delete
|
636
|
+
params_not_allowed.push(:id)
|
637
|
+
params.delete :id
|
653
638
|
end
|
639
|
+
end
|
640
|
+
else
|
641
|
+
if JSONAPI.configuration.raise_if_parameters_not_allowed
|
642
|
+
fail JSONAPI::Exceptions::ParameterNotAllowed.new(key, error_object_overrides)
|
643
|
+
else
|
644
|
+
params_not_allowed.push(key)
|
645
|
+
params.delete key
|
646
|
+
end
|
654
647
|
end
|
655
648
|
end
|
656
649
|
|
@@ -666,22 +659,22 @@ module JSONAPI
|
|
666
659
|
|
667
660
|
def parse_add_relationship_operation(resource_klass, verified_params, relationship, parent_key)
|
668
661
|
if relationship.is_a?(JSONAPI::Relationship::ToMany)
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
662
|
+
@operations << JSONAPI::Operation.new(
|
663
|
+
:create_to_many_relationships,
|
664
|
+
resource_klass,
|
665
|
+
context: @context,
|
666
|
+
resource_id: parent_key,
|
667
|
+
relationship_type: relationship.name,
|
668
|
+
data: verified_params[:to_many].values[0]
|
676
669
|
)
|
677
670
|
end
|
678
671
|
end
|
679
672
|
|
680
673
|
def parse_update_relationship_operation(resource_klass, verified_params, relationship, parent_key)
|
681
674
|
options = {
|
682
|
-
|
683
|
-
|
684
|
-
|
675
|
+
context: @context,
|
676
|
+
resource_id: parent_key,
|
677
|
+
relationship_type: relationship.name
|
685
678
|
}
|
686
679
|
|
687
680
|
if relationship.is_a?(JSONAPI::Relationship::ToOne)
|
@@ -702,23 +695,23 @@ module JSONAPI
|
|
702
695
|
operation_type = :replace_to_many_relationships
|
703
696
|
end
|
704
697
|
|
705
|
-
JSONAPI::Operation.new(operation_type, resource_klass, options)
|
698
|
+
@operations << JSONAPI::Operation.new(operation_type, resource_klass, options)
|
706
699
|
end
|
707
700
|
|
708
701
|
def parse_remove_relationship_operation(resource_klass, params, relationship, parent_key)
|
709
702
|
operation_base_args = [resource_klass].push(
|
710
|
-
|
711
|
-
|
712
|
-
|
703
|
+
context: @context,
|
704
|
+
resource_id: parent_key,
|
705
|
+
relationship_type: relationship.name
|
713
706
|
)
|
714
707
|
|
715
708
|
if relationship.is_a?(JSONAPI::Relationship::ToMany)
|
716
709
|
operation_args = operation_base_args.dup
|
717
710
|
keys = params[:to_many].values[0]
|
718
711
|
operation_args[1] = operation_args[1].merge(associated_keys: keys)
|
719
|
-
JSONAPI::Operation.new(:remove_to_many_relationships, *operation_args)
|
712
|
+
@operations << JSONAPI::Operation.new(:remove_to_many_relationships, *operation_args)
|
720
713
|
else
|
721
|
-
JSONAPI::Operation.new(:remove_to_one_relationship, *operation_base_args)
|
714
|
+
@operations << JSONAPI::Operation.new(:remove_to_one_relationship, *operation_base_args)
|
722
715
|
end
|
723
716
|
end
|
724
717
|
|