I have a Rails API which accepts only JSON as input. If I fail to include a header of Content-Type: application/json, then request.headers['Content-Type'] defaults to application/x-www-form-urlencoded and the params do not get parsed properly. The whole json body becomes a key in the params. The result is a 422, which is confusing to API users.
How can I change this to default to parsing as json if no Content-Type header is supplied?
Lots of other questions answer how to do this with the response format. To change this default, you can specify it in the controller with:
request.format = :json
Or in a route namespace with something like:
namespace :api, defaults: {format: :json} do
This, however, changes the default response format and does not change the default request format. What I need to do is to change the default request format for parsing parameters.
Here is my admittedly terrible solution derived from the suggestion in Micael Nussbaumer's answer. I'd love it if some Rubyists could magically turn this ugly hack into a pithy one liner.
module Api
class BaseApiController < ActionController::API
private
# This is an ugly hack needed to make it default to json if you do not
# specify a Content-Type. If you see this and know of a better way please
# say so!
def params
if !@params
if request.headers["Content-Type"]=="application/x-www-form-urlencoded"
body_string = request.body.read
begin
hash = JSON.parse(body_string)
@params = ActionController::Parameters.new(hash)
rescue
# do nothing
end
end
if !@params
@params = super
end
end
@params
end
...
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With