The rackal
gem provides convenience helpers when configuring Rack applications.
The main intent is abstract away some common boilerplate and reduce hardcoded details in
application configuration, especially in config.ru
, in a way that still allows some
direct control of how it is applied.
Rackal was originally developed to simplify set up of Roda apps but is intended to not assume or depend on Roda. As of this writing, no testing with Sinatra or bare Rack apps has been performed, so milage may vary. This gem is still considered experimental (at least until version number is updated to at least 0.1.0).
- Environment aware: "production", "staging", "test", and "development" are recognized (based on ENV['RACK_ENV'])
- Database configuration: easy access to database configuration (based on YAML configuration file)
- Application metadata: easy access to application details (trivial YAML configuration file)
- Application protection: easy use of Refrigerator gem (when available)
Easy setup for application logging is being considered for inclusion in Rackal.
require 'rackal'
# support logging
if Rackal.environment.unprotected? # by default: "development" or "test" is unprotected
require 'logger'
logger = Logger.new($stdout)
end
require 'roda'
Gem.ruby
# these output lines demonstrate some use
puts "Starting #{Rackal.application.name} in #{Rackal.environment.env} environment."
# => Starting MyApp in production environment.
puts "(root directory is \"#{Rackal.root}\")"
# => (root directory is "/home/someuser/src/my_app")
run(Rackal.application.main_class.freeze.app) # main_class is the driving class of the application
Rackal.protect! # applies Refrigerator if gem is present in production settings
An demonstration application using Rackal will be provided in a later version.
Available as namespaced methods:
Rackal.application
returns an object allowing access to various application metadataRackal.root
returns the inferred root directory of the application (same asRackal.appliation.root
)Rackal.database_parameters
returns Hash of database connection attributes (see below)Rackal.environment
returns an object allowing access to various runtime environment (e.g., "production") metadataRackal.env
convenience use ofENV
array (with caching) (e.g.,Rackal.env("RACK_ENV")
==ENV["RACK_ENV"]
)Rackal.protect!
applies Refrigerator gem (if available) to lock/freeze the application during run time. Merely returnsfalse
if gem is not available.
If ENV["RACK_ENV"]
is nil
for whatever reason, Rackal will assume a development environment.
Two configuration files, written in YAML, will be assumed to be under /config
directory for
the application: database.yml
and rackal.yml
If adhering to the twelve-factor app standard, recall that deploy-level configuration should not included in code, but application configuration can be.
Rackal does not interfere with use of tools like dotenv
or figaro to support deploy-level environment variable.
Merely add that to the application startup (e.g., config.ru
) in the usual way before
calling any Rackal methods.
Since the YAML files used for Rackal's configuration support ERB, those files can then
follow the environment variables supplied dynamically when wanted, while leaving
application-level directly supplied. The database.yml
example below shows such a use
for credentials.
The database.yml
file is just to collect, by runtime environment, the parameters for
connecting to the database.
If Rackal.database_parameters
is never called, this YAML file need not be present.
Example (for Sequel using Postgres):
default: &default
adapter: 'postgres'
# host: 'some_db_url'
# port: '5432'
database: 'myapp'
max_connections: 10
username: <%= Rackal.env('MYAPP_DATABASE_USERNAME') %>
password: <%= Rackal.env('MYAPP_DATABASE_PASSWORD') %>
development:
<<: *default
host: 'localhost'
database: 'myapp_dev'
test:
<<: *default
host: 'localhost'
database: 'myapp_test'
staging:
<<: *default
production:
<<: *default
For the given runtime environment, the configured parameters are available in code via
Rackal.database_parameters
which provides a Hash (using symbols as keys):
Rackal.database_parameters[:database]
# => "myapp_test" if ENV['RACK_ENV'] == "test"
The rackal.yml
file is for any specifics to inform Rackal of assumptions it can make.
Presently, only the name of the application is configured to support inference of how to refer to it in the boilerplate it abstracts away (e.g., class name, source file name).
If neither Rackal.root
nor Rackal.application
are ever called (unlikely), this YAML file
need not be present.
Example:
rackal:
app_main: 'SomeApp' # note that this is the class name, provided as a string
app_main
: class name of the main class used to drive the application.- The string, as given, is available in code as
Rackal.application.name
- The class, as a constant, is available in case as
Rackal.application.main_class
- The string, as given, is available in code as
Given that one key feature of Roda is its performance and memory footprint, care was taken to avoid interferring with that. Any cost is constrained as much as possible to only application startup:
- Rackal is expected to add minimal time to application startup.
- Rackal is expected to consume marginally additional memory in the application for holding its state once the application has started.
Rigorous performance testing has not yet been done to ensure those claims.
Since a Gemfile is used for testing and development conveniences without polluting the
gem itself, be sure to bundle install
. RSpec, simplecov, and rubocop are assumed, but
only RSpec itself is required.
The provided RSpec tests have strong coverage for regression testing. Mutation testing will be attempted soon.
Further development is invited to better support Roda applications, extensions and generalization for non-Roda Rack applications, and performance improvements.
Jeremy Evans's roda-sequel-stack
repository
was used as an original reference for boilerplate (though the "up"/"down" mechanics for
database migrations are not considered in Rackal).
Some application metadata concepts were inspired by Rails (for instance, Rackal.root
),
though with a much lighter (and so less robust) approach taken in Rackal.
- Rackal (primarily
Rackal.root
) assumes use in a Linux style OS and so assumes/
as the path delimiter. - Right now,
Rackal.database_parameters
has only been tested with Sequel ORM for database connections, though the use of YAML to produce the Hash should be universally capable. - (As stated in the introduction to this notes,) Rackal has not been tested with a bare Rack application or with a Sinatra application.
Please report issues or bugs.
Rackal is released under the MIT License.