Rack

26
Introduction to Rack Kerry Buckley, 26 October 2010

description

 

Transcript of Rack

Page 1: Rack

Introduction to RackKerry Buckley, 26 October 2010

Page 2: Rack

Introduction to Rack

Why was it needed?

How does it work?

Building a stack with middleware

Writing a simple rack application

Page 3: Rack

Web frameworks

and many more…

Page 4: Rack

Web servers

Mongrel

Webrick

CGI

Page 5: Rack

Before Rack

Page 6: Rack

With Rack

Rack-compliant interface

Page 7: Rack

Introduction to Rack

Why was it needed?

How does it work?

Building a stack with middleware

Writing a simple rack application

Page 8: Rack

Rack is just aninterface specification

Page 9: Rack

A Rack app is…

• An object (not a class)…

• …which responds to call(env)…

• …and returns an array containing:

• response code

• a hash of headers

• the body**this is a slight simplification

Page 10: Rack

The environment hash

• REQUEST_METHOD

• SERVER_NAME, SERVER_PORT

• SCRIPT_NAME, PATH_INFO, QUERY_STRING

• HTTP_ variables from request headers

• Some rack-specific variables

Page 11: Rack

A simple Rack app

require 'rubygems'require 'rack'

class HelloWorld  def call(env)    [200, {"Content-Type" => "text/html"}, "Hello World!"]  endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

Page 12: Rack

require 'rubygems'require 'rack'

Rack::Handler::Mongrel.run proc { |env|  [200, {"Content-Type" => "text/html"}, "Hello World!"]}, :Port => 9292

Even simpler Rack app

Page 13: Rack

Revisiting the body

• An object (not a class)…

• …which responds to call(env)…

• …and returns an array containing:

• response code

• a hash of headers

• the body**this is a slight simplification

Page 14: Rack

Revisiting the body

• Must respond to each, yielding strings

• Strings work in 1.8, but not 1.9

• close will be called if present

• to_path can provide a file location

Page 15: Rack

Body as array

require 'rubygems'require 'rack'

class HelloWorld  def call(env)    [200, {"Content-Type" => "text/html"}, ["Hello ", "World!"]]  endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

Page 16: Rack

Body as IO object

require 'rubygems'require 'rack'

class HelloWorld  def call(env)    [200, {"Content-Type" => "text/html"},      StringIO.new("Hello World!")]  endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

Page 17: Rack

Body as self

require 'rubygems'require 'rack'

class HelloWorld  def call(env)    [200, {"Content-Type" => "text/html"}, self]  end

  def each    yield "Hello "    yield "World!"  endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

Page 18: Rack

The rackup file

• Configuration DSL for a Rack app

• Server-independent

• Allows stacking of middleware

• Provides simple route mapping

Page 19: Rack

The rackup file

class HelloWorld  def call(env)    [200, {"Content-Type" => "text/html"}, "Hello World!"]  endend

run HelloWorld.new

config_file = File.read(config)rack_application = eval("Rack::Builder.new { #{config_file} }")server.run rack_application, options

Your config.ru file:

Rack loads it like this:

Page 20: Rack

The rack gem

Provides a bunch of helper classes

• Request/response wrappers

• Logging

• Authentication (basic and digest)

• Cookies and sessions

• Mock requests and responses

Page 21: Rack

Introduction to Rack

Why was it needed?

How does it work?

Building a stack with middleware

Writing a simple rack application

Page 22: Rack

Middleware

Middleware A

Middleware B

Application

Request

Request

Request

Response

Response

Response

Page 23: Rack

Middleware

• A middleware is just a rack application

• Constructor takes next app down

• Can modify request or response

• Can call layer below, or just return

• Configured with ‘use’ in rackup file

Page 24: Rack

Middleware in Rails

• Used internally for cookies, parameter parsing etc

• Add your own in environment.rb:

Rails::Initializer.run do |config|    config.middleware.use "MyMiddlewareClass"  end 

Page 25: Rack

Introduction to Rack

Why was it needed?

How does it work?

Building a stack with middleware

Writing a simple rack application

Page 26: Rack

Demo!