Force all received requests Content-Type to JSON

Mich picture Mich · Apr 10, 2014 · Viewed 7.9k times · Source

I'm actually working on an API which uses Rails 4. I would like to set the Content-Type of a request to JSON if the client does not specify a media type in Content-Type header.

In order to get that behaviour I tried to add the following before_action in my ApplicationController :

def set_request_default_content_type
  request.format = :json
end

In my RegistrationsController#create method I have a breakpoint to check if everything is working. Well, the request.format trick does not work, despite the value is set to application/json it seems that the controller (or Rails internals) do not consider the received request's Content-Type as JSON.

I did a POST request with the following body (and no Content-Type) :

{"user" : {"email":"[email protected]","password":"foobarfoo"}}

By debugging with Pry I see that :

 [2] api(#<V1::RegistrationsController>) _  request.format.to_s
 => "application/json"
 [3] api(#<V1::RegistrationsController>) _  params
 => {
       "action" => "create",
   "controller" => "v1/registrations"
 }

It means that Rails did not have considered my request with the request.format configured with Mime::JSON, but instead with Mime::ALL and so it didn't parse the request's JSON body. :(

Answer

ErvalhouS picture ErvalhouS · Feb 15, 2018

You could define a any type response inside the respond_to block, which will not restrict your controller to respond when request uri ends with .json, it also relief you from defining a response type explicitly and will keep, independently of request content-type, responding as you wish, example:

respond_to do |format|
  format.any  {render :json => {foo: 'bar'}}
end