SlideShare a Scribd company logo
1 of 54
Download to read offline
Your best friend Rack
What is Rack?
     Rack provides a minimal interface

“     between webservers supporting
       Ruby and Ruby frameworks.

Transparently integrates in your existing
           rails, sinatra apps

 Helps you easily create a middleware
     standalone application stack
Yeah! but... what is
         Rack?
 A Rack application is a Ruby object
  that responds to call. It takes exactly
 one argument, the environment and
   returns an Array of exactly three
values: The status, the headers, and the
                  body.
A basic Rack app
    diagram
Minimum server
  interface you said?
app = lambda d o |env|
  [200,
    { 'Content-Type' => 'text/html'
   'Hello World']
end
run app
Where does Rack sit?
Rack is a full
middleware stack
Allows a modular design
What is a middleware?
    Rack application that is designed

“     to run in conjunction with
    another Rack application, which
          acts as the endpoint
...
 Think of a Rack middleware as a filter
receiving the Rack environment for the
request from the previous middleware

   Does some work with or on the
      request's environment

Then calls the next middleware in the
                chain
...
      The last Rack application in the

“      chain is the application itself

     Any middleware in the chain can
return the Rack response itself, thus
preventing the rest of the middlewares
     in the chain from executing
Installation
$... $ gem install rack
Successfully installed rack-1.2.1
1 gem installed
Installing ri documentation for rack-1.2.1...
Building YARD (yri) index for rack-1.2.1...
Installing RDoc documentation for rack-1.2.1...
Let's talk more Rack
status, headers, body = object

[200,
  { 'Content-Type' => 'text/html' }
  'Hello World']
Stacking apps
m o d u l e MyModule
   c l a s s Upcase
       d e f initialize app
           @app = app
       end
    d e f call env
       p 'upcase'
       status, headers, body =
       [status, headers, [body.
    end
  end
end
...
m o d u l e MyModule
   c l a s s Reverse
       d e f initialize app
           @app = app
       end
    d e f call env
       p 'reverse'
       status, headers, body =
       [status, headers, [body.
    end
  end
end
...
use MyModule::Upcase
use MyModule::Reverse
use Rack::ContentLength
app = lambda { |env| [200, { 'Content
run app
...
$...$ rackup stacked1.ru &
[1] 2123
...$ curl localhost:9292
"upcase"
"reverse"
127.0.0.1 - - [03/Nov/2010 16:15:34] "GET / HTTP/
DLROW OLLEH
...$
What happened?
A Decorator pattern happens

    In OOP, the decorator pattern is

“      a design pattern that allows
     new/additional behaviour to be
        added to an existing object
              dynamically
Basic API
use(middleware, **args, &block) adds
      a middleware to the stack

 run(app) dispatches to an application

  map(path, &block) constructs a
 Rack::URLMap in a convenient way
Basic API - usage
       example
r e q u i r e 'rack-validate'

use Rack::Validate

map '/hello' d o
  run lambda d o |env|
    [200,
      { 'Content-Type' => 'text/html'
      'Hello World']
  end
end
Rake::Validate from
http://coderack.org/
Basic optional usage -
   Rack::Builder
Provides an optional DSL
app = Rack::Builder.new d o
  map "/hello" d o
    run lambda d o |env|
      [200,
        { 'Content-Type' => 'text/html'
        'Hello World']
    end
  end
end
Rack convenience
 Wanna develop outside of existing
 frameworks, implement your own
   ones, or develop middleware?

Rack provides many helpers to create
Rack applications quickly and without
  doing the same web stuff all over
Rack::Request
req = Rack::Request.new(env)
req.post?
req.params["data"]
Rack::Response
res = Response.new
res.write "<title>Lobstericious!</title>"
res.write "<pre>"
res.write lobster
res.write "</pre>"
res.write "<p><a href='#{href}'>flip!</a>
res.write "<p><a href='?flip=crash'>crash
res.finish
use Rack::CommonLogger
Writes a log statement to STDOUT in the Apache
      common log format for each request
         use Rack::ShowExceptions
   Renders a nice looking errors page for all
            unhandled exceptions
                use Rack::Lint
 Ensures that your Rack application conforms to
   the Rack spec. Rack::Lint will generate an
exception if the response of your application does
              not meet the Rack spec
And many more
     Rack::Auth::Basic

   Rack::Session::Cookie

       Rack::Sendfile

     http://coderack.org/

http://rack.rubyforge.org/doc/
Is this testable?
   Use your favorite framework

It provides Rack::MockRequest and
        Rack::MockResponse
With bacon

      Bacon is a small RSpec clone

“    weighing less than 350 LoC but
    nevertheless providing all essential
                 features.
MockRequest
describe Rack::Static d o
  root = File.expand_path(File.dirname(_ _ F I L E _ _
                                        _
  OPTIONS = {:urls => ["/cgi"], :root => root

  @request =
    Rack::MockRequest.new(
      Rack::Static.new(DummyApp.new, OPTIONS
  it "serves files" d o
    res = @request.get("/cgi/test")
    res.should.be.ok
    res.body.should =~ /ruby/
  end
end
MockResponse
describe Rack::Chunked d o
  before d o
    @env = Rack::MockRequest.
      env_for('/', 'HTTP_VERSION' => '1.1', 'REQUEST_METH
  end

  should 'chunk responses with no Content-Length' d o
    app = lambda { |env| [200, {}, ['Hello',
    response = Rack::MockResponse.new(
      *Rack::Chunked.new(app).call(@env))
    response.headers.should.n o t .i n c l u d e 'Content-Le
                                n     i
    response.headers['Transfer-Encoding'].should
    response.body.should.equal
        "5rnHellorn1rn rn6rnWorld!rn0rnrn"
  end
end
Why do we care?
   Supported web servers
     Mongrel, EventedMongrel,
       SwiftipliedMongrel

WEBrick, FCGI, CGI, SCGI, LiteSpeed

               Thin
These web servers include
handlers in their distributions
       Ebb, Fuzed, Glassfish v3

 Phusion Passenger (which is mod_rack
       for Apache and for nginx)

     Rainbows!, Unicorn, Zbatery
Any valid Rack app will run
the same on all these handlers,
  without changing anything
Supported web
   frameworks
Camping, Coset, Halcyon, Mack

       Maveric, Merb,
 Racktools::SimpleApplication

  Ramaze, Rum, Sinatra, Sin

       Vintage, Waves

   Wee, … and many others.
Of course Ruby on Rails
Rails has adopted the Rack philosophy
       throughout the framework

    A Rails application is actually a
     collection of Rack and Rails
 middleware components that all work
 together to form the completed whole
Listing the rails middleware
            stack
$...(master) $ rake middleware
(in /home/chischaschos/Projects/salary-manager)
use ActionDispatch::Static
use Rack::Lock
use ActiveSupport::Cache::Strategy::LocalCache
use Rack::Runtime
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::RemoteIp
use Rack::Sendfile
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::MethodOverride
use ActionDispatch::Head
use ActionDispatch::BestStandardsSupport
use Warden::Manager
use Sass::Plugin::Rack
run SalaryManager::Application.routes
Things to note
 The Rack application being run with
the run directive at the end of the list of
 middlewares is the Rails application's
                 routes
Rails controllers are
   rack compliant
  A controller declaration
c l a s s HomeController < ApplicationCont
   d e f index
       render :text => "I'm your home cont
   end
end
Rails console testing (had to
    shorten the output)
$ruby-1.8.7-p302 > ...$ rails console
Loading development environment (Rails 3.0.0)
ruby-1.8.7-p302 > app = RailsRackApp::Application
ruby-1.8.7-p302 > app.class
 => ActionDispatch::Routing::RouteSet
ruby-1.8.7-p302 > env = {'REQUEST_METHOD' => 'GET
 => {"PATH_INFO"=>"/home/index", "REQUEST_METHOD"
ruby-1.8.7-p302 > status, headers, body = app.cal
 => [200, {"ETag"=>""d47cb2eec6f22cb9ff6fbb21cd3
ruby-1.8.7-p302 > body.body
 => "I'm yout home controller's body"
Rack app from a controller
       declaration
$ruby-1.8.7-p302 > app = HomeController.action :i
 => #<Proc:0xb6e26664@/home/chischaschos/.rvm/gem
ruby-1.8.7-p302 > app.respond_to? 'call'
 => true
ruby-1.8.7-p302 > status, headers, body = app.cal
=> [200, {"ETag"=>""d47cb2eec6f22cb9ff6fbb21cd34
ruby-1.8.7-p302 > body.body
 => "I'm yout home controller's body"
There are two different ways to
 install Rack components into
     your Rails application
 1 - Either configure your Rack application as part
      of your application's middleware stack

  2 - Or you can route URI paths directly to the
 Rack application from you application's routes
1.1 - Installing a component into your
               application
          lib/average_time.rb
 c l a s s AverageRuntime
    @@requests = 0
    @@total_runtime = 0.0
   d e f initialize(app)
      @app = app
   end

   d e f call(env)
      code, headers, body = @app.call(env

     @@requests += 1
     @@total_runtime += headers['X-Runtime'
     headers['X-AverageRuntime'] =
       (@@total_runtime / @@requests).to_s

     [code, headers, body]
   end
1.2 - Inserting the middleware
          config/application.rb
r e q u i r e File.expand_path('../boot', _ _ F I L E _ _
r e q u i r e 'rails/all'
Bundler.r e q u i r e (:default, Rails.env)
              r
m o d u l e RailsRackApp
   c l a s s Application < Rails::Application

     # starts the important part
     config.autoload_paths += %W(#{config
     config.middleware.insert_before Rack
       "AverageRuntime"
     # end the important part
    config.encoding = "utf-8"
    config.filter_parameters += [:password
  end
end
1.3 - Verifying middleware is in the
                stack
$...$ rake middleware
(in /home/chischaschos/Projects/rack-testing/rails-rack-app)
use ActionDispatch::Static
use Rack::Lock
use AverageRuntime
use ActiveSupport::Cache::Strategy::LocalCache
use Rack::Runtime
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::RemoteIp
use Rack::Sendfile
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::MethodOverride
use ActionDispatch::Head
use ActionDispatch::BestStandardsSupport
run RailsRackApp::Application.routes
1.4 Testing our middleware
Look at X-Averageruntime: header
 $...$ curl -I localhost:3000
 HTTP/1.1 404 Not Found
 Connection: Keep-Alive
 Content-Type: text/html
 Date: Fri, 05 Nov 2010 16:04:43 GMT
 Server: WEBrick/1.3.1 (Ruby/1.8.7/2010-08-16)
 X-Runtime: 0.312526
 Content-Length: 621
 X-Averageruntime: 0.312526
2.1 - Routing to a rack application
         lib/walking_arrow.rb
c l a s s WalkingArrow
  ARROW = '=>'
  @@spaces = 0
  d e f call(env)
     @@spaces += 1
     [200, {'Content-Type' => 'text/plain'},
  end
end
2.2 - Add a route
        lib/walking_arrow.rb
r e q u i r e 'lib/walking_arrow.rb'
RailsRackApp::Application.routes.draw
   get 'home/index'
   get 'walkingarrow' => WalkingArrow.new
end
2.3 Testing our middleware
              Walk!!!
$...$ curl localhost:3000/walkingarrow
 =>
...$ curl localhost:3000/walkingarrow
  =>
...$ curl localhost:3000/walkingarrow
    =>
...$ curl localhost:3000/walkingarrow
     =>
...$ curl localhost:3000/walkingarrow
       =>
...$ curl localhost:3000/walkingarrow
        =>
Before diving into rack
  and rails creation
 Learn and play with some examples

    http://guides.rubyonrails.org
           /railsonrack.html
Do you have ideas on
   how to use it?
Most sincere thanks to
     http://rack.rubyforge.org/doc/

  http://rails-nutshell.labs.oreilly.com
                /ch07.html

http://rubylearning.com/blog/2010/09/21
   /writing-modular-web-applications-
  with-rack/?utmsource=twitterfeed&
           utmmedium=twitter

              And Mendo
References
github repo and examples

  chischaschos twitter

More Related Content

What's hot

Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Ryan Weaver
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
The Evolution of Airbnb's Frontend
The Evolution of Airbnb's FrontendThe Evolution of Airbnb's Frontend
The Evolution of Airbnb's FrontendSpike Brehm
 
Introduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman OrtegaIntroduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman Ortegaarman o
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101Samantha Geitz
 
AnsibleFest 2014 - Role Tips and Tricks
AnsibleFest 2014 - Role Tips and TricksAnsibleFest 2014 - Role Tips and Tricks
AnsibleFest 2014 - Role Tips and Tricksjimi-c
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and othersYusuke Wada
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleRaimonds Simanovskis
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Alberto Perdomo
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Racksickill
 
Laravel 5 In Depth
Laravel 5 In DepthLaravel 5 In Depth
Laravel 5 In DepthKirk Bushell
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkBo-Yi Wu
 
Apache Jackrabbit Oak - Scale your content repository to the cloud
Apache Jackrabbit Oak - Scale your content repository to the cloudApache Jackrabbit Oak - Scale your content repository to the cloud
Apache Jackrabbit Oak - Scale your content repository to the cloudRobert Munteanu
 
Symfony bundle fo asynchronous job processing
Symfony bundle fo asynchronous job processingSymfony bundle fo asynchronous job processing
Symfony bundle fo asynchronous job processingWojciech Ciołko
 
Cloud meets Fog & Puppet A Story of Version Controlled Infrastructure
Cloud meets Fog & Puppet A Story of Version Controlled InfrastructureCloud meets Fog & Puppet A Story of Version Controlled Infrastructure
Cloud meets Fog & Puppet A Story of Version Controlled InfrastructureHabeeb Rahman
 

What's hot (20)

Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
Finally, Professional Frontend Dev with ReactJS, WebPack & Symfony (Symfony C...
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
The Evolution of Airbnb's Frontend
The Evolution of Airbnb's FrontendThe Evolution of Airbnb's Frontend
The Evolution of Airbnb's Frontend
 
Introduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman OrtegaIntroduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman Ortega
 
REST APIs in Laravel 101
REST APIs in Laravel 101REST APIs in Laravel 101
REST APIs in Laravel 101
 
AnsibleFest 2014 - Role Tips and Tricks
AnsibleFest 2014 - Role Tips and TricksAnsibleFest 2014 - Role Tips and Tricks
AnsibleFest 2014 - Role Tips and Tricks
 
Tatsumaki
TatsumakiTatsumaki
Tatsumaki
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Fast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on OracleFast Web Applications Development with Ruby on Rails on Oracle
Fast Web Applications Development with Ruby on Rails on Oracle
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
 
Getting Started With Aura
Getting Started With AuraGetting Started With Aura
Getting Started With Aura
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Laravel 5 In Depth
Laravel 5 In DepthLaravel 5 In Depth
Laravel 5 In Depth
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
Apache Jackrabbit Oak - Scale your content repository to the cloud
Apache Jackrabbit Oak - Scale your content repository to the cloudApache Jackrabbit Oak - Scale your content repository to the cloud
Apache Jackrabbit Oak - Scale your content repository to the cloud
 
Symfony bundle fo asynchronous job processing
Symfony bundle fo asynchronous job processingSymfony bundle fo asynchronous job processing
Symfony bundle fo asynchronous job processing
 
Cloud meets Fog & Puppet A Story of Version Controlled Infrastructure
Cloud meets Fog & Puppet A Story of Version Controlled InfrastructureCloud meets Fog & Puppet A Story of Version Controlled Infrastructure
Cloud meets Fog & Puppet A Story of Version Controlled Infrastructure
 
Express JS
Express JSExpress JS
Express JS
 
Catalyst MVC
Catalyst MVCCatalyst MVC
Catalyst MVC
 

Similar to What is Rack? A concise overview of the Ruby web server interface

Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareAlona Mekhovova
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails DevsDiacode
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkDaniel Spector
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Railsanides
 
Rails in the bowels
Rails in the bowelsRails in the bowels
Rails in the bowelsCreditas
 
TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011Lance Ball
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular applicationmirrec
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Webnickmbailey
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Jesus Manuel Olivas
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - IntroductionVagmi Mudumbai
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发shaokun
 

Similar to What is Rack? A concise overview of the Ruby web server interface (20)

Rack
RackRack
Rack
 
Rack
RackRack
Rack
 
Rack
RackRack
Rack
 
Using and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middlewareUsing and scaling Rack and Rack-based middleware
Using and scaling Rack and Rack-based middleware
 
Dev streams2
Dev streams2Dev streams2
Dev streams2
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
 
RoR guide_p1
RoR guide_p1RoR guide_p1
RoR guide_p1
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
Rails in the bowels
Rails in the bowelsRails in the bowels
Rails in the bowels
 
TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011TorqueBox - Ruby Hoedown 2011
TorqueBox - Ruby Hoedown 2011
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular application
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Web
 
Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...Creating a modern web application using Symfony API Platform, ReactJS and Red...
Creating a modern web application using Symfony API Platform, ReactJS and Red...
 
Rack
RackRack
Rack
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - Introduction
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
rails.html
rails.htmlrails.html
rails.html
 

Recently uploaded

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Recently uploaded (20)

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

What is Rack? A concise overview of the Ruby web server interface

  • 2. What is Rack? Rack provides a minimal interface “ between webservers supporting Ruby and Ruby frameworks. Transparently integrates in your existing rails, sinatra apps Helps you easily create a middleware standalone application stack
  • 3. Yeah! but... what is Rack? A Rack application is a Ruby object that responds to call. It takes exactly one argument, the environment and returns an Array of exactly three values: The status, the headers, and the body.
  • 4. A basic Rack app diagram
  • 5. Minimum server interface you said? app = lambda d o |env| [200, { 'Content-Type' => 'text/html' 'Hello World'] end run app
  • 7. Rack is a full middleware stack
  • 9. What is a middleware? Rack application that is designed “ to run in conjunction with another Rack application, which acts as the endpoint
  • 10. ... Think of a Rack middleware as a filter receiving the Rack environment for the request from the previous middleware Does some work with or on the request's environment Then calls the next middleware in the chain
  • 11. ... The last Rack application in the “ chain is the application itself Any middleware in the chain can return the Rack response itself, thus preventing the rest of the middlewares in the chain from executing
  • 12. Installation $... $ gem install rack Successfully installed rack-1.2.1 1 gem installed Installing ri documentation for rack-1.2.1... Building YARD (yri) index for rack-1.2.1... Installing RDoc documentation for rack-1.2.1...
  • 13. Let's talk more Rack status, headers, body = object [200, { 'Content-Type' => 'text/html' } 'Hello World']
  • 14. Stacking apps m o d u l e MyModule c l a s s Upcase d e f initialize app @app = app end d e f call env p 'upcase' status, headers, body = [status, headers, [body. end end end
  • 15. ... m o d u l e MyModule c l a s s Reverse d e f initialize app @app = app end d e f call env p 'reverse' status, headers, body = [status, headers, [body. end end end
  • 16. ... use MyModule::Upcase use MyModule::Reverse use Rack::ContentLength app = lambda { |env| [200, { 'Content run app
  • 17. ... $...$ rackup stacked1.ru & [1] 2123 ...$ curl localhost:9292 "upcase" "reverse" 127.0.0.1 - - [03/Nov/2010 16:15:34] "GET / HTTP/ DLROW OLLEH ...$
  • 18. What happened? A Decorator pattern happens In OOP, the decorator pattern is “ a design pattern that allows new/additional behaviour to be added to an existing object dynamically
  • 19.
  • 20. Basic API use(middleware, **args, &block) adds a middleware to the stack run(app) dispatches to an application map(path, &block) constructs a Rack::URLMap in a convenient way
  • 21. Basic API - usage example r e q u i r e 'rack-validate' use Rack::Validate map '/hello' d o run lambda d o |env| [200, { 'Content-Type' => 'text/html' 'Hello World'] end end
  • 23. Basic optional usage - Rack::Builder Provides an optional DSL app = Rack::Builder.new d o map "/hello" d o run lambda d o |env| [200, { 'Content-Type' => 'text/html' 'Hello World'] end end end
  • 24. Rack convenience Wanna develop outside of existing frameworks, implement your own ones, or develop middleware? Rack provides many helpers to create Rack applications quickly and without doing the same web stuff all over
  • 26. Rack::Response res = Response.new res.write "<title>Lobstericious!</title>" res.write "<pre>" res.write lobster res.write "</pre>" res.write "<p><a href='#{href}'>flip!</a> res.write "<p><a href='?flip=crash'>crash res.finish
  • 27. use Rack::CommonLogger Writes a log statement to STDOUT in the Apache common log format for each request use Rack::ShowExceptions Renders a nice looking errors page for all unhandled exceptions use Rack::Lint Ensures that your Rack application conforms to the Rack spec. Rack::Lint will generate an exception if the response of your application does not meet the Rack spec
  • 28. And many more Rack::Auth::Basic Rack::Session::Cookie Rack::Sendfile http://coderack.org/ http://rack.rubyforge.org/doc/
  • 29. Is this testable? Use your favorite framework It provides Rack::MockRequest and Rack::MockResponse
  • 30. With bacon Bacon is a small RSpec clone “ weighing less than 350 LoC but nevertheless providing all essential features.
  • 31. MockRequest describe Rack::Static d o root = File.expand_path(File.dirname(_ _ F I L E _ _ _ OPTIONS = {:urls => ["/cgi"], :root => root @request = Rack::MockRequest.new( Rack::Static.new(DummyApp.new, OPTIONS it "serves files" d o res = @request.get("/cgi/test") res.should.be.ok res.body.should =~ /ruby/ end end
  • 32. MockResponse describe Rack::Chunked d o before d o @env = Rack::MockRequest. env_for('/', 'HTTP_VERSION' => '1.1', 'REQUEST_METH end should 'chunk responses with no Content-Length' d o app = lambda { |env| [200, {}, ['Hello', response = Rack::MockResponse.new( *Rack::Chunked.new(app).call(@env)) response.headers.should.n o t .i n c l u d e 'Content-Le n i response.headers['Transfer-Encoding'].should response.body.should.equal "5rnHellorn1rn rn6rnWorld!rn0rnrn" end end
  • 33. Why do we care? Supported web servers Mongrel, EventedMongrel, SwiftipliedMongrel WEBrick, FCGI, CGI, SCGI, LiteSpeed Thin
  • 34. These web servers include handlers in their distributions Ebb, Fuzed, Glassfish v3 Phusion Passenger (which is mod_rack for Apache and for nginx) Rainbows!, Unicorn, Zbatery
  • 35. Any valid Rack app will run the same on all these handlers, without changing anything
  • 36. Supported web frameworks Camping, Coset, Halcyon, Mack Maveric, Merb, Racktools::SimpleApplication Ramaze, Rum, Sinatra, Sin Vintage, Waves Wee, … and many others.
  • 37. Of course Ruby on Rails Rails has adopted the Rack philosophy throughout the framework A Rails application is actually a collection of Rack and Rails middleware components that all work together to form the completed whole
  • 38. Listing the rails middleware stack $...(master) $ rake middleware (in /home/chischaschos/Projects/salary-manager) use ActionDispatch::Static use Rack::Lock use ActiveSupport::Cache::Strategy::LocalCache use Rack::Runtime use Rails::Rack::Logger use ActionDispatch::ShowExceptions use ActionDispatch::RemoteIp use Rack::Sendfile use ActionDispatch::Callbacks use ActiveRecord::ConnectionAdapters::ConnectionManagement use ActiveRecord::QueryCache use ActionDispatch::Cookies use ActionDispatch::Session::CookieStore use ActionDispatch::Flash use ActionDispatch::ParamsParser use Rack::MethodOverride use ActionDispatch::Head use ActionDispatch::BestStandardsSupport use Warden::Manager use Sass::Plugin::Rack run SalaryManager::Application.routes
  • 39. Things to note The Rack application being run with the run directive at the end of the list of middlewares is the Rails application's routes
  • 40. Rails controllers are rack compliant A controller declaration c l a s s HomeController < ApplicationCont d e f index render :text => "I'm your home cont end end
  • 41. Rails console testing (had to shorten the output) $ruby-1.8.7-p302 > ...$ rails console Loading development environment (Rails 3.0.0) ruby-1.8.7-p302 > app = RailsRackApp::Application ruby-1.8.7-p302 > app.class => ActionDispatch::Routing::RouteSet ruby-1.8.7-p302 > env = {'REQUEST_METHOD' => 'GET => {"PATH_INFO"=>"/home/index", "REQUEST_METHOD" ruby-1.8.7-p302 > status, headers, body = app.cal => [200, {"ETag"=>""d47cb2eec6f22cb9ff6fbb21cd3 ruby-1.8.7-p302 > body.body => "I'm yout home controller's body"
  • 42. Rack app from a controller declaration $ruby-1.8.7-p302 > app = HomeController.action :i => #<Proc:0xb6e26664@/home/chischaschos/.rvm/gem ruby-1.8.7-p302 > app.respond_to? 'call' => true ruby-1.8.7-p302 > status, headers, body = app.cal => [200, {"ETag"=>""d47cb2eec6f22cb9ff6fbb21cd34 ruby-1.8.7-p302 > body.body => "I'm yout home controller's body"
  • 43. There are two different ways to install Rack components into your Rails application 1 - Either configure your Rack application as part of your application's middleware stack 2 - Or you can route URI paths directly to the Rack application from you application's routes
  • 44. 1.1 - Installing a component into your application lib/average_time.rb c l a s s AverageRuntime @@requests = 0 @@total_runtime = 0.0 d e f initialize(app) @app = app end d e f call(env) code, headers, body = @app.call(env @@requests += 1 @@total_runtime += headers['X-Runtime' headers['X-AverageRuntime'] = (@@total_runtime / @@requests).to_s [code, headers, body] end
  • 45. 1.2 - Inserting the middleware config/application.rb r e q u i r e File.expand_path('../boot', _ _ F I L E _ _ r e q u i r e 'rails/all' Bundler.r e q u i r e (:default, Rails.env) r m o d u l e RailsRackApp c l a s s Application < Rails::Application # starts the important part config.autoload_paths += %W(#{config config.middleware.insert_before Rack "AverageRuntime" # end the important part config.encoding = "utf-8" config.filter_parameters += [:password end end
  • 46. 1.3 - Verifying middleware is in the stack $...$ rake middleware (in /home/chischaschos/Projects/rack-testing/rails-rack-app) use ActionDispatch::Static use Rack::Lock use AverageRuntime use ActiveSupport::Cache::Strategy::LocalCache use Rack::Runtime use Rails::Rack::Logger use ActionDispatch::ShowExceptions use ActionDispatch::RemoteIp use Rack::Sendfile use ActionDispatch::Callbacks use ActiveRecord::ConnectionAdapters::ConnectionManagement use ActiveRecord::QueryCache use ActionDispatch::Cookies use ActionDispatch::Session::CookieStore use ActionDispatch::Flash use ActionDispatch::ParamsParser use Rack::MethodOverride use ActionDispatch::Head use ActionDispatch::BestStandardsSupport run RailsRackApp::Application.routes
  • 47. 1.4 Testing our middleware Look at X-Averageruntime: header $...$ curl -I localhost:3000 HTTP/1.1 404 Not Found Connection: Keep-Alive Content-Type: text/html Date: Fri, 05 Nov 2010 16:04:43 GMT Server: WEBrick/1.3.1 (Ruby/1.8.7/2010-08-16) X-Runtime: 0.312526 Content-Length: 621 X-Averageruntime: 0.312526
  • 48. 2.1 - Routing to a rack application lib/walking_arrow.rb c l a s s WalkingArrow ARROW = '=>' @@spaces = 0 d e f call(env) @@spaces += 1 [200, {'Content-Type' => 'text/plain'}, end end
  • 49. 2.2 - Add a route lib/walking_arrow.rb r e q u i r e 'lib/walking_arrow.rb' RailsRackApp::Application.routes.draw get 'home/index' get 'walkingarrow' => WalkingArrow.new end
  • 50. 2.3 Testing our middleware Walk!!! $...$ curl localhost:3000/walkingarrow => ...$ curl localhost:3000/walkingarrow => ...$ curl localhost:3000/walkingarrow => ...$ curl localhost:3000/walkingarrow => ...$ curl localhost:3000/walkingarrow => ...$ curl localhost:3000/walkingarrow =>
  • 51. Before diving into rack and rails creation Learn and play with some examples http://guides.rubyonrails.org /railsonrack.html
  • 52. Do you have ideas on how to use it?
  • 53. Most sincere thanks to http://rack.rubyforge.org/doc/ http://rails-nutshell.labs.oreilly.com /ch07.html http://rubylearning.com/blog/2010/09/21 /writing-modular-web-applications- with-rack/?utmsource=twitterfeed& utmmedium=twitter And Mendo
  • 54. References github repo and examples chischaschos twitter