Parsing MessagePack to Rails params
Update
ActionDispatch::ParamsParser
has been deprecated in Rails 5.0.Below solution works for Rails versions before 5.1 where
ActionDispatch::ParamsParser
got removed.Checkout this post for similar implementation in current Rails versions.
Recently I had to develop Ruby on Rails app which would handle MessagePack formatted request bodies as well as JSON. By default Rails makes parsed JSON available at the params object, and I wanted MessagePack content to be handled just like that.
ActionDispatch::ParamsParser is a Rack middleware responsible for this behavior. Extending it to support other serialization formats could be done in following manner.
I started by including mgspack_rails to Gemfile
and then
wrote my custom middleware at app/middlewares/custom_params_parser.rb
extending ParamsParser to preserve default behavior.
class CustomParamsParser < ActionDispatch::ParamsParser
def initialize(app, parsers={}, &block)
super app,
parsers.merge({
Mime[:msgpack] => lambda {|raw_post|
data = ActiveSupport::MessagePack.decode(raw_post)
data.is_a?(Hash) ? data : { _msgpack: data }
}
}),
&block
end
end
Then I replaced default ParamsParser in the middleware stack by including
following to the config/application.rb
:
config.middleware.swap 'ActionDispatch::ParamsParser', 'CustomParamsParser'
It should be noted while writing tests, that middleware stack is not available at the functional controller tests. Integration tests have to be used when it’s necessary to include request body data to params or to test custom middleware like the one above.