Avoid parsing Rails controller params by using Metal

Need more metal!

Hands by Incase is licensed under CC BY 2.0

I was looking at this controller today, which was using lots of memory:


class WebhooksController < ApplicationController
  def create
    if SomeModel.exists?(params[:model_id])
      ProcessJSONinSidekiq.perform_later(params.to_json)
    end
    render json: {}
  end
end

Most of the memory (and time) was coming from the fact that this was receiving a large amount of JSON, which gets converted to the params Hash (actually ActionController::Parameters) which we then convert back to JSON for a Sidekiq job.

We can do better.

First, I needed to move the SomeModel.exists? check into the job, which was pretty easy.

Next, I can send the raw JSON to the Sidekiq job using request.raw_post, rather than calling params.to_json :


class WebhooksController < ApplicationController
  def create
    ProcessJSONinSidekiq.perform_later(request.raw_post)
    render json: {}
  end
end

Rails will still automatically convert the JSON to the params Hash though, and that is still unnecessary for us.

I realized at this point we really should be using ActionController::API instead of ApplicationController because it is leaner and more efficient for API-related requests (no view rendering, etc.). That didn’t go far enough here though. I needed metal. 🤘🏻

ActionController::Metal is lower level than ActionController::API and removes pretty much everything. It does have a concept of params, but they aren’t loaded unless you use the method. I had to tweak my return a bit, but it was pretty simple. Now I never touch the JSON. I simply send it along.


class WebhooksController < ActionController::Metal
  def create
    ProcessJSONinSidekiq.perform_later(request.raw_post)
    [200, { "Content-Type" => "application/json" }, "{}"]
  end
end

Photo of Daniel Morrison

Daniel founded Collective Idea in 2005 to put a name to his growing and already full-time freelance work. He works hard writing code, teaching, and mentoring.

Comments