views:

92

answers:

1

Hi,

I have a create action that handles XML requests. Rather than using the built in params hash, I use Nokogiri to validate the XML against an XML schema. If this validation passes, the raw XML is stored for later processing.

As far as I understand, the XML is parsed twice: First the Rails creates the params hash, then the Nokogiri parsing happens. I've been looking for ways to disable the params parsing to speed things up but have found nothing.

ActionController::Base.param_parsers[Mime::XML] = lambda do |body|
  # something
end

I know it's possible to customize the XML params parsing in general using something like the above, but I depend on the default behaviour in other controllers.

Is it possible to bypass the params parsing on a per-action basis? What options do I have?

Thank you for your help!

+1  A: 

I've managed to solve the problem using Rails Metal. The relevant part looks something like this:

class ReportMetal
  def self.call(env) 
    if env["PATH_INFO"] =~ /^\/reports/
      request = Rack::Request.new(env)
      if request.post?
        report = Report.new(:raw_xml => request.body.string)
        if report.save # this triggers the nokogiri validation on raw_xml
          return [201, { 'Content-Type' => 'application/xml' }, report.to_xml]
        else
          return [422, { 'Content-Type' => 'application/xml' }, report.errors.to_xml]
        end
      end
    end
    [404, { "Content-Type" => "text/html" }, "Not Found."]
  ensure
    ActiveRecord::Base.clear_active_connections!
  end
end

Thanks!

PS: Naive benchmarking with Apache Bench in development shows 22.62 Requests per second for standard Rails vs. 57.60 Requests per second for the Metal version.

Sebastian
This looks like what I need :) Thanks!
Thibaut Barrère
Confirmed - it works - thanks again!
Thibaut Barrère