Your SlideShare is downloading. ×
Your best friend Rack
What is Rack?     Rack provides a minimal interface“     between webservers supporting       Ruby and Ruby frameworks.Tran...
Yeah! but... what is         Rack? A Rack application is a Ruby object  that responds to call. It takes exactly one argume...
A basic Rack app    diagram
Minimum server  interface you said?app = lambda d o |env|  [200,    { Content-Type => text/html   Hello World]endrun app
Where does Rack sit?
Rack is a fullmiddleware stack
Allows a modular design
What is a middleware?    Rack application that is designed“     to run in conjunction with    another Rack application, wh...
... Think of a Rack middleware as a filterreceiving the Rack environment for therequest from the previous middleware   Does...
...      The last Rack application in the“      chain is the application itself     Any middleware in the chain canreturn ...
Installation$... $ gem install rackSuccessfully installed rack-1.2.11 gem installedInstalling ri documentation for rack-1....
Lets talk more Rackstatus, headers, body = object[200,  { Content-Type => text/html }  Hello World]
Stacking appsm o d u l e MyModule   c l a s s Upcase       d e f initialize app           @app = app       end    d e f ca...
...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   ...
...use MyModule::Upcaseuse MyModule::Reverseuse Rack::ContentLengthapp = lambda { |env| [200, { Contentrun app
...$...$ rackup stacked1.ru &[1] 2123...$ curl localhost:9292"upcase""reverse"127.0.0.1 - - [03/Nov/2010 16:15:34] "GET / ...
What happened?A Decorator pattern happens    In OOP, the decorator pattern is“      a design pattern that allows     new/a...
Basic APIuse(middleware, **args, &block) adds      a middleware to the stack run(app) dispatches to an application  map(pa...
Basic API - usage       exampler e q u i r e rack-validateuse Rack::Validatemap /hello d o  run lambda d o |env|    [200, ...
Rake::Validate fromhttp://coderack.org/
Basic optional usage -   Rack::BuilderProvides an optional DSLapp = Rack::Builder.new d o  map "/hello" d o    run lambda ...
Rack convenience Wanna develop outside of existing frameworks, implement your own   ones, or develop middleware?Rack provi...
Rack::Requestreq = Rack::Request.new(env)req.post?req.params["data"]
Rack::Responseres = Response.newres.write "<title>Lobstericious!</title>"res.write "<pre>"res.write lobsterres.write "</pr...
use Rack::CommonLoggerWrites a log statement to STDOUT in the Apache      common log format for each request         use R...
And many more     Rack::Auth::Basic   Rack::Session::Cookie       Rack::Sendfile     http://coderack.org/http://rack.rubyfo...
Is this testable?   Use your favorite frameworkIt provides Rack::MockRequest and        Rack::MockResponse
With bacon      Bacon is a small RSpec clone“    weighing less than 350 LoC but    nevertheless providing all essential   ...
MockRequestdescribe Rack::Static d o  root = File.expand_path(File.dirname(_ _ F I L E _ _                                ...
MockResponsedescribe Rack::Chunked d o  before d o    @env = Rack::MockRequest.      env_for(/, HTTP_VERSION => 1.1, REQUE...
Why do we care?   Supported web servers     Mongrel, EventedMongrel,       SwiftipliedMongrelWEBrick, FCGI, CGI, SCGI, Lit...
These web servers includehandlers in their distributions       Ebb, Fuzed, Glassfish v3 Phusion Passenger (which is mod_rac...
Any valid Rack app will runthe same on all these handlers,  without changing anything
Supported web   frameworksCamping, Coset, Halcyon, Mack       Maveric, Merb, Racktools::SimpleApplication  Ramaze, Rum, Si...
Of course Ruby on RailsRails has adopted the Rack philosophy       throughout the framework    A Rails application is actu...
Listing the rails middleware            stack$...(master) $ rake middleware(in /home/chischaschos/Projects/salary-manager)...
Things to note The Rack application being run withthe run directive at the end of the list of middlewares is the Rails app...
Rails controllers are   rack compliant  A controller declarationc l a s s HomeController < ApplicationCont   d e f index  ...
Rails console testing (had to    shorten the output)$ruby-1.8.7-p302 > ...$ rails consoleLoading development environment (...
Rack app from a controller       declaration$ruby-1.8.7-p302 > app = HomeController.action :i => #<Proc:0xb6e26664@/home/c...
There are two different ways to install Rack components into     your Rails application 1 - Either configure your Rack appl...
1.1 - Installing a component into your               application          lib/average_time.rb c l a s s AverageRuntime    ...
1.2 - Inserting the middleware          config/application.rbr e q u i r e File.expand_path(../boot, _ _ F I L E _ _r e q u...
1.3 - Verifying middleware is in the                stack$...$ rake middleware(in /home/chischaschos/Projects/rack-testing...
1.4 Testing our middlewareLook at X-Averageruntime: header $...$ curl -I localhost:3000 HTTP/1.1 404 Not Found Connection:...
2.1 - Routing to a rack application         lib/walking_arrow.rbc l a s s WalkingArrow  ARROW = =>  @@spaces = 0  d e f ca...
2.2 - Add a route        lib/walking_arrow.rbr e q u i r e lib/walking_arrow.rbRailsRackApp::Application.routes.draw   get...
2.3 Testing our middleware              Walk!!!$...$ curl localhost:3000/walkingarrow =>...$ curl localhost:3000/walkingar...
Before diving into rack  and rails creation Learn and play with some examples    http://guides.rubyonrails.org           /...
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.htm...
Referencesgithub repo and examples  chischaschos twitter
Intro to Rack
Upcoming SlideShare
Loading in...5
×

Intro to Rack

3,779

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
3,779
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
38
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Intro to Rack"

  1. 1. Your best friend Rack
  2. 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. 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 threevalues: The status, the headers, and the body.
  4. 4. A basic Rack app diagram
  5. 5. Minimum server interface you said?app = lambda d o |env| [200, { Content-Type => text/html Hello World]endrun app
  6. 6. Where does Rack sit?
  7. 7. Rack is a fullmiddleware stack
  8. 8. Allows a modular design
  9. 9. What is a middleware? Rack application that is designed“ to run in conjunction with another Rack application, which acts as the endpoint
  10. 10. ... Think of a Rack middleware as a filterreceiving the Rack environment for therequest from the previous middleware Does some work with or on the requests environmentThen calls the next middleware in the chain
  11. 11. ... The last Rack application in the“ chain is the application itself Any middleware in the chain canreturn the Rack response itself, thuspreventing the rest of the middlewares in the chain from executing
  12. 12. Installation$... $ gem install rackSuccessfully installed rack-1.2.11 gem installedInstalling 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. 13. Lets talk more Rackstatus, headers, body = object[200, { Content-Type => text/html } Hello World]
  14. 14. Stacking appsm 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 endend
  15. 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 endend
  16. 16. ...use MyModule::Upcaseuse MyModule::Reverseuse Rack::ContentLengthapp = lambda { |env| [200, { Contentrun app
  17. 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. 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. 19. Basic APIuse(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
  20. 20. Basic API - usage exampler e q u i r e rack-validateuse Rack::Validatemap /hello d o run lambda d o |env| [200, { Content-Type => text/html Hello World] endend
  21. 21. Rake::Validate fromhttp://coderack.org/
  22. 22. Basic optional usage - Rack::BuilderProvides an optional DSLapp = Rack::Builder.new d o map "/hello" d o run lambda d o |env| [200, { Content-Type => text/html Hello World] end endend
  23. 23. Rack convenience Wanna develop outside of existing frameworks, implement your own ones, or develop middleware?Rack provides many helpers to createRack applications quickly and without doing the same web stuff all over
  24. 24. Rack::Requestreq = Rack::Request.new(env)req.post?req.params["data"]
  25. 25. Rack::Responseres = Response.newres.write "<title>Lobstericious!</title>"res.write "<pre>"res.write lobsterres.write "</pre>"res.write "<p><a href=#{href}>flip!</a>res.write "<p><a href=?flip=crash>crashres.finish
  26. 26. use Rack::CommonLoggerWrites 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 anexception if the response of your application does not meet the Rack spec
  27. 27. And many more Rack::Auth::Basic Rack::Session::Cookie Rack::Sendfile http://coderack.org/http://rack.rubyforge.org/doc/
  28. 28. Is this testable? Use your favorite frameworkIt provides Rack::MockRequest and Rack::MockResponse
  29. 29. With bacon Bacon is a small RSpec clone“ weighing less than 350 LoC but nevertheless providing all essential features.
  30. 30. MockRequestdescribe 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/ endend
  31. 31. MockResponsedescribe 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" endend
  32. 32. Why do we care? Supported web servers Mongrel, EventedMongrel, SwiftipliedMongrelWEBrick, FCGI, CGI, SCGI, LiteSpeed Thin
  33. 33. These web servers includehandlers in their distributions Ebb, Fuzed, Glassfish v3 Phusion Passenger (which is mod_rack for Apache and for nginx) Rainbows!, Unicorn, Zbatery
  34. 34. Any valid Rack app will runthe same on all these handlers, without changing anything
  35. 35. Supported web frameworksCamping, Coset, Halcyon, Mack Maveric, Merb, Racktools::SimpleApplication Ramaze, Rum, Sinatra, Sin Vintage, Waves Wee, … and many others.
  36. 36. Of course Ruby on RailsRails 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
  37. 37. Listing the rails middleware stack$...(master) $ rake middleware(in /home/chischaschos/Projects/salary-manager)use ActionDispatch::Staticuse Rack::Lockuse ActiveSupport::Cache::Strategy::LocalCacheuse Rack::Runtimeuse Rails::Rack::Loggeruse ActionDispatch::ShowExceptionsuse ActionDispatch::RemoteIpuse Rack::Sendfileuse ActionDispatch::Callbacksuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacheuse ActionDispatch::Cookiesuse ActionDispatch::Session::CookieStoreuse ActionDispatch::Flashuse ActionDispatch::ParamsParseruse Rack::MethodOverrideuse ActionDispatch::Headuse ActionDispatch::BestStandardsSupportuse Warden::Manageruse Sass::Plugin::Rackrun SalaryManager::Application.routes
  38. 38. Things to note The Rack application being run withthe run directive at the end of the list of middlewares is the Rails applications routes
  39. 39. Rails controllers are rack compliant A controller declarationc l a s s HomeController < ApplicationCont d e f index render :text => "Im your home cont endend
  40. 40. Rails console testing (had to shorten the output)$ruby-1.8.7-p302 > ...$ rails consoleLoading development environment (Rails 3.0.0)ruby-1.8.7-p302 > app = RailsRackApp::Applicationruby-1.8.7-p302 > app.class => ActionDispatch::Routing::RouteSetruby-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"=>""d47cb2eec6f22cb9ff6fbb21cd3ruby-1.8.7-p302 > body.body => "Im yout home controllers body"
  41. 41. Rack app from a controller declaration$ruby-1.8.7-p302 > app = HomeController.action :i => #<Proc:0xb6e26664@/home/chischaschos/.rvm/gemruby-1.8.7-p302 > app.respond_to? call => trueruby-1.8.7-p302 > status, headers, body = app.cal=> [200, {"ETag"=>""d47cb2eec6f22cb9ff6fbb21cd34ruby-1.8.7-p302 > body.body => "Im yout home controllers body"
  42. 42. There are two different ways to install Rack components into your Rails application 1 - Either configure your Rack application as part of your applications middleware stack 2 - Or you can route URI paths directly to the Rack application from you applications routes
  43. 43. 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
  44. 44. 1.2 - Inserting the middleware config/application.rbr e q u i r e File.expand_path(../boot, _ _ F I L E _ _r e q u i r e rails/allBundler.r e q u i r e (:default, Rails.env) rm 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 endend
  45. 45. 1.3 - Verifying middleware is in the stack$...$ rake middleware(in /home/chischaschos/Projects/rack-testing/rails-rack-app)use ActionDispatch::Staticuse Rack::Lockuse AverageRuntimeuse ActiveSupport::Cache::Strategy::LocalCacheuse Rack::Runtimeuse Rails::Rack::Loggeruse ActionDispatch::ShowExceptionsuse ActionDispatch::RemoteIpuse Rack::Sendfileuse ActionDispatch::Callbacksuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacheuse ActionDispatch::Cookiesuse ActionDispatch::Session::CookieStoreuse ActionDispatch::Flashuse ActionDispatch::ParamsParseruse Rack::MethodOverrideuse ActionDispatch::Headuse ActionDispatch::BestStandardsSupportrun RailsRackApp::Application.routes
  46. 46. 1.4 Testing our middlewareLook 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
  47. 47. 2.1 - Routing to a rack application lib/walking_arrow.rbc l a s s WalkingArrow ARROW = => @@spaces = 0 d e f call(env) @@spaces += 1 [200, {Content-Type => text/plain}, endend
  48. 48. 2.2 - Add a route lib/walking_arrow.rbr e q u i r e lib/walking_arrow.rbRailsRackApp::Application.routes.draw get home/index get walkingarrow => WalkingArrow.newend
  49. 49. 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 =>
  50. 50. Before diving into rack and rails creation Learn and play with some examples http://guides.rubyonrails.org /railsonrack.html
  51. 51. Do you have ideas on how to use it?
  52. 52. Most sincere thanks to http://rack.rubyforge.org/doc/ http://rails-nutshell.labs.oreilly.com /ch07.htmlhttp://rubylearning.com/blog/2010/09/21 /writing-modular-web-applications- with-rack/?utmsource=twitterfeed& utmmedium=twitter And Mendo
  53. 53. Referencesgithub repo and examples chischaschos twitter

×