Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rack is Spectacular

Rack is Spectacular

Barcamp Miami 2010

Bryce "BonzoESC" Kerley

February 21, 2010
Tweet

More Decks by Bryce "BonzoESC" Kerley

Other Decks in Programming

Transcript

  1. Rack • Standard Ruby-HTTP interface • Write (framework) once •

    Run anywhere (that is Rack-compatible) • Rails, Sinatra, Camping • Mongrel, Passenger, Unicorn
  2. A Rack Application use Rack::ContentLength run(proc do [ 200, {

    'Content-type' => 'text/plain'}, 'hello world'] end) Response Code Response Headers Response Body c9c340bb config.ru
  3. What is Rails • ActionPack • Router - maps URLs

    to code • Controller - environment for code • View - generating response body • ActiveRecord - database access
  4. The Essential Rails • ActionPack • Router - maps URLs

    to code • Controller - environment for code • View - generating response body • ActiveRecord - database access
  5. module Spectacular class App def call(environment) [ 200, { 'Content-type'

    => 'text/plain'}, 'hello world'] end end end require 'lib/spectacular.rb' use Rack::ContentLength run(Spectacular::App.new) config.ru lib/spectacular/app.rb 0fad6a02
  6. module Spectacular class App … def call(environment) method = environment['REQUEST_METHOD']

    path = environment['PATH_INFO'] @dispatcher.dispatch method, path, environment rescue => exception error_backtrace exception, environment end private def error_backtrace(exception, environment) exception_info = “some html” [500, { 'Content-type' => 'text/html'}, exception_info] end … end end lib/spectacular/app.rb 2a0d1445 breaks; no dispatcher yet
  7. But That’s Okay • We’re not building Rails • It’s

    okay if we Fail to Scale • Just use an array to map paths to controllers and actions
  8. def get_route(path) @routes.detect{ |r| path === r[0] } end …

    class RoutePen def route(path, controller, method) @routes << [path, controller, method] end end 9cfb9609 lib/spectacular/dispatcher.rb
  9. def response_for(method) @method = method send @method [response_code, headers, body]

    end … def template_file File.join(APP_DIR, 'views', controller_name, "#{@method}.html.haml") end … def body return @body if defined? @body template = File.read template_file engine = Haml::Engine.new template @body = engine.render end ce2f00a3 lib/spectacular/controller.rb
  10. class HelloController < Spectacular::Controller def index end end hello world

    app/controllers/hello_controller.rb app/views/hello/index.html.haml ce2f00a3
  11. === 0 :> /abc/ === 'abc' # => true 0

    :> String === 'abc' # => true 0 :> /too+t/ === 'toooooooooot' # => true
  12. Using the Path class TootController < Spectacular::Controller def toot @toot

    = @path.gsub('/','') end end app/controllers/toot_controller.rb %h1=@toot app/views/toot/toot.html.haml 48b08205
  13. 404 • When we can’t figure out how to process

    a request, that should be a “404” • We can simply make a wildcard route
  14. route //, ErrorController, :not_found app/routes.rb class ErrorController < Spectacular::Controller def

    not_found @response_code = 404 end end app/controllers/error_controller.rb 2a2653b2
  15. What’s Left • Only renders HAML • No layouts •

    Can’t easily render a different view • No query parameters • No POST