Skip to content

Commit 1923af6

Browse files
authored
Merge pull request #4 from oozou/chore/render_error_when_nil_deserialized
Render error when unable to deserialize resource
2 parents 14a9421 + dfaf98a commit 1923af6

File tree

6 files changed

+79
-2
lines changed

6 files changed

+79
-2
lines changed

lib/generators/jsonapi/initializer/templates/initializer.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@
6969
# # Set a default pagination scheme.
7070
# config.jsonapi_pagination = ->(_) { {} }
7171
#
72+
# # Set the default action when the payload cannot be deserialized
73+
# config.jsonapi_payload_malformed = -> {
74+
# render jsonapi_errors: {
75+
# title: 'Non-compliant Request Body',
76+
# detail: 'The request was not formatted in compliance with the application/vnd.api+json spec',
77+
# links: {
78+
# about: 'http://jsonapi.org/format/'
79+
# }
80+
# }, status: :bad_request
81+
# }
82+
#
83+
# # Uncomment to take no action when the payload cannot be deserialized
84+
# config.jsonapi_payload_malformed = nil
85+
#
7286
# # Set a logger.
7387
# config.logger = Logger.new(STDOUT)
7488
#

lib/jsonapi/rails/configuration.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,30 @@ module Configurable
3939

4040
DEFAULT_JSONAPI_PAGINATION = ->(_) { {} }
4141

42+
DEFAULT_JSONAPI_PAYLOAD_MALFORMED = -> {
43+
render jsonapi_errors: {
44+
title: 'Non-compliant Request Body',
45+
detail: 'The request was not formatted in compliance with the application/vnd.api+json spec',
46+
links: {
47+
about: 'http://jsonapi.org/format/'
48+
}
49+
}, status: :bad_request
50+
}
51+
4252
DEFAULT_LOGGER = Logger.new(STDERR)
4353

4454
DEFAULT_CONFIG = {
55+
jsonapi_cache: DEFAULT_JSONAPI_CACHE,
4556
jsonapi_class: DEFAULT_JSONAPI_CLASS,
4657
jsonapi_errors_class: DEFAULT_JSONAPI_ERRORS_CLASS,
47-
jsonapi_cache: DEFAULT_JSONAPI_CACHE,
4858
jsonapi_expose: DEFAULT_JSONAPI_EXPOSE,
4959
jsonapi_fields: DEFAULT_JSONAPI_FIELDS,
5060
jsonapi_include: DEFAULT_JSONAPI_INCLUDE,
5161
jsonapi_links: DEFAULT_JSONAPI_LINKS,
5262
jsonapi_meta: DEFAULT_JSONAPI_META,
5363
jsonapi_object: DEFAULT_JSONAPI_OBJECT,
5464
jsonapi_pagination: DEFAULT_JSONAPI_PAGINATION,
65+
jsonapi_payload_malformed: DEFAULT_JSONAPI_PAYLOAD_MALFORMED,
5566
logger: DEFAULT_LOGGER
5667
}.freeze
5768

lib/jsonapi/rails/controller/deserialization.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def deserializable_resource(key, options = {}, &block)
5555
"Unable to deserialize #{key} because no JSON API payload was" \
5656
" found. (#{controller.controller_name}##{params[:action]})"
5757
end
58+
controller.jsonapi_payload_malformed
5859
next
5960
end
6061

lib/jsonapi/rails/controller/hooks.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ def jsonapi_meta
6969
def jsonapi_pagination(resources)
7070
instance_exec(resources, &JSONAPI::Rails.config[:jsonapi_pagination])
7171
end
72+
73+
# Hook for rendering jsonapi_errors when no payload passed
74+
def jsonapi_payload_malformed
75+
return unless JSONAPI::Rails.config[:jsonapi_payload_malformed]
76+
instance_exec(&JSONAPI::Rails.config[:jsonapi_payload_malformed])
77+
end
7278
end
7379
end
7480
end

spec/deserialization_spec.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,47 @@ def create
9393
expect(controller.jsonapi_pointers).to eq(expected)
9494
end
9595
end
96+
97+
context 'when unable to deserialize resource from params' do
98+
controller do
99+
deserializable_resource :user
100+
101+
def create
102+
render plain: :ok
103+
end
104+
end
105+
106+
context 'with the default config' do
107+
it 'makes the deserialized resource available in params' do
108+
post :create
109+
110+
expect(response.body).to eq(
111+
{
112+
:errors => [
113+
{
114+
:links => {
115+
:about => "http://jsonapi.org/format/"
116+
},
117+
:title => "Non-compliant Request Body",
118+
:detail => "The request was not formatted in compliance with the application/vnd.api+json spec"
119+
}
120+
],
121+
:jsonapi => {
122+
:version=>"1.0"
123+
}
124+
}.to_json
125+
)
126+
expect(response).to be_bad_request
127+
end
128+
end
129+
130+
context 'when the config[:jsonapi_payload_malformed] == nil' do
131+
it 'makes the deserialization mapping available via #jsonapi_pointers' do
132+
with_config(jsonapi_payload_malformed: nil) { post :create }
133+
134+
expect(response.body).to eq('ok')
135+
expect(response).to be_success
136+
end
137+
end
138+
end
96139
end

spec/dummy/config/initializers/new_framework_defaults.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
Rails.application.config.active_record.belongs_to_required_by_default = true
1919

2020
# Do not halt callback chains when a callback returns false. Previous versions had true.
21-
ActiveSupport.halt_callback_chains_on_return_false = false
21+
if Rails.version.to_f < 5.2
22+
ActiveSupport.halt_callback_chains_on_return_false = false
23+
end
2224

2325
# Configure SSL options to enable HSTS with subdomains. Previous versions had false.
2426
Rails.application.config.ssl_options = { hsts: { subdomains: true } }

0 commit comments

Comments
 (0)