Overriding the default Content-Type

Viewed 2717

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.

3 Answers

I've solved it with middleware this way for Rails API (rails new my_project --api)

config:

# config/application.rb
# ...
require './lib/middleware/consider_all_request_json_middleware'
# ...

module MyApplication
    # ...
  class Application < Rails::Application
        # ...
        config.middleware.insert_before(ActionDispatch::Static,ConsiderAllRequestJsonMiddleware)
        # ...

middleware:

# lib/middleware/consider_all_request_json_middleware.rb
class ConsiderAllRequestJsonMiddleware
  def initialize app
    @app = app
  end

  def call(env)
    if env["CONTENT_TYPE"] == 'application/x-www-form-urlencoded'
      env["CONTENT_TYPE"] = 'application/json'
    end
    @app.call(env)
  end
end

original: https://blog.eq8.eu/til/content-type-applicationjson-by-default-in-rails-5.html

Related