Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
yet another rack router
require 'router'
use Rack::Static, :urls => ['/css', '/js'], :root => "static"
run Router.new
# /controllers/default.rb
module Controllers
class Default
def self.default env
[200, {'content-type' => 'text/html'}, "default text"]
end
end
end
require 'yaml'
# Instantiating the Router class does a couple things:
# 1. read route definition file, and generate case/when logic
# 2. define a "call" function (called by Rack) that calls the appropriate controller.action pair
#
# Routes are defined as "<path pattern> <controller name> <action name>"
#
# Example routes.yml
# # pattern Controller action
# - /user/\d+ User note
# - /users User index
# - / Default default
#
# Controllers are assumed to be wrapped in a "Controllers" module
# Actions are assumed to be static, and accept the env object
#
# For example,
# module Controllers
# class Foo
# def static.default env
# [200, {'content-type' => 'text/html'}, "foo"]
# end
# end
# end
require 'yaml'
require './controllers.rb'
class Router
def initialize
whens = ''
YAML.load_file('routes.yml').each do |route|
pattern, controller, action = route.split /\s+/
whens += <<-EOS
when %r{#{pattern}}
controller = Controllers::#{controller}.new env
controller.#{action}
controller.response
EOS
end
Router.class_eval <<-EOS
def call env
case env['REQUEST_PATH']
#{whens}
end
end
EOS
end
end
# pattern Controller action
- /user/\d+ User find
- /user User default
- / Default default
# /controllers/user.rb
module Controllers
class User
def self.default env
[200, {'content-type' => 'text/html'}, "User#default"]
end
def self.find env
[200, {'content-type' => 'text/html'}, "User#find"]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment