Thanks to visit codestin.com
Credit goes to Github.com

Skip to content

Pass a request object to middleware rather than a hash #1879

@tenderlove

Description

@tenderlove

One problem I see in many middleware is that they "cast" the env hash to a Rack request object, do some manipulations, then pass then cast it back to a hash and pass it on.

For example:

def call(env)
  req = Rack::Request.new(env)

  # do stuff with req

  @app.call(req.env)
end

I would really like it if we could stop allocating request objects all the time, but since every middleware is passed a hash it's something that happens quite frequently.

I would like to do 2 things:

  1. Make a middleware that casts the env hash to a request object, then passes the request object to the next middleware
  2. Make the request object quack enough like a hash that existing legacy middleware can use the request object as if it was the env hash

Step 1 could be as simple as this:

class CastsToRequest
  def initialize(app)
    @app = app
  end
  def call(env); @app.call(Rack::Request.new(env)); end
end

If some middleware want to take advantage of this "pre allocated" request object, then they would require that CastsToRequest is in the middleware stack above them. Those middleware would no longer have to cast back and forth between hash and request object.

If the Rack::Request object quacks enough like a hash, then users could add legacy middleware without changing anything, though they could be upgraded to take advantage of the request object.

I think this idea could work because it should be OK for any middleware to say "yes I work with any Rack compatible web server, but I must be run after the CastsToRequest middleware. I think this would also unlock the ability for web servers to start passing their own request objects to middleware (as long as they quack the same as Rack::Request).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions