Skip to content

Managing environments. #1546

@ioquatix

Description

@ioquatix

RACK_ENV as a variable has many confusing use cases, and many of them don't completely align up.

  • In some cases, it's used to configure the middleware in config.ru. Value include :test, :development, and :production. Frameworks are migrating to use APP_ENV instead.
  • In Rack::Server it's used to control the default middleware. Values include :development and :deployment.

I propose that we do the following:

1/ Change Rack::Builder to take an optional environment parameter, which can be used during the construction of the config.ru.

# config.ru

if environment?(:production)
  use ReportErrors
else
  use LogErrors
end

# ...

Then:

Rack::Builder.new(environment: 'production')

We can still feed RACK_ENV into this if required, but we decouple it and provide a non-global state interface for users.

2/ Provide some kind of "load an app" function under Rack::Handler.

Rack::Handler.load_app(path, environment)

The point is, if Rack::Builder is not sufficient for generating the app, what is? Do we want to provide an interface for servers like Puma, Falcon, so they can essentially say: give me a rack middleware, for this environment, from this configuration file.

In particular, I was looking at the middleware situation. Based on what @tenderlove told me, we can almost remove environment from the server, but I feel like there is value in automatically adding lint and so on during development.

So, either we clearly define values for environment and what middleware they load, or we leave that up to downstream libraries, e.g. rack-test can add Rack::Lint.

Some discussion here would be good. However, I may try throwing together a PR just so we have something actionable.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions