Your SlideShare is downloading. ×
  • Like
Rack Middleware
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply
Published

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
3,800
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
57
Comments
0
Likes
4

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Rack Middleware
  • 2. m/
  • 3. NEED
  • 4. CHOICE
  • 5. Jon Crosby http://joncrosby.me
  • 6. CloudKit http://getcloudkit.com
  • 7. rack-contrib http://github.com/rack/rack-contrib
  • 8. Engine Yard Solo “The platform for on-demand management of your Ruby on Rails application in the cloud.”
  • 9. Free during HackFest
  • 10. Discount for Sign Up
  • 11. CGI
  • 12. app.cgi
  • 13. WARNING
  • 14. Contains Perl
  • 15. old skool perl cgi
  • 16. if ($cgi->param(‘action’) eq ‘all’) { my $sql = “select * from customer”; my $rows = $dbh->selectall_arrayref($sql); if (@$rows) { print “<table border=1>” . “<th>name</th>” . ...
  • 17. if ($cgi->param(‘action’) eq ‘all’) { my $sql = “select * from customer”; my $rows = $dbh->selectall_arrayref($sql); if (@$rows) { print “<table border=1>” . “<th>name</th>” . ...
  • 18. if ($cgi->param(‘action’) eq ‘all’) { my $sql = “select * from customer”; my $rows = $dbh->selectall_arrayref($sql); if (@$rows) { print “<table border=1>” . “<th>name</th>” . ...
  • 19. if ($cgi->param(‘action’) eq ‘all’) { my $sql = “select * from customer”; my $rows = $dbh->selectall_arrayref($sql); if (@$rows) { print “<table border=1>” . “<th>name</th>” . ...
  • 20. if ($cgi->param(‘action’) eq ‘all’) { my $sql = “select * from customer”; my $rows = $dbh->selectall_arrayref($sql); if (@$rows) { print “<table border=1>” . “<th>name</th>” . ...
  • 21. if ($cgi->param(‘action’) eq ‘all’) { my $sql = “select * from customer”; my $rows = $dbh->selectall_arrayref($sql); if (@$rows) { print “<table border=1>” . “<th>name</th>” . ...
  • 22. Monolith
  • 23. :-(
  • 24. Rails
  • 25. Merb Sinatra Mack Ramaze Waves
  • 26. Authentication
  • 27. Single Sign-On
  • 28. Caching
  • 29. Authentication Example: OpenID + OAuth
  • 30. Install Auth Plugin(s)
  • 31. Install Auth Plugin(s) Generate Controllers
  • 32. Install Auth Plugin(s) Generate Controllers Generate Models
  • 33. Install Auth Plugin(s) Generate Controllers Generate Models Generate Migrations
  • 34. Install Auth Plugin(s) Generate Controllers Generate Models Generate Migrations Modify Existing Controllers
  • 35. Install Auth Plugin(s) Generate Controllers Generate Models Generate Migrations Modify Existing Controllers Monkey Patch Rails
  • 36. :-(
  • 37. The Web
  • 38. HTTP
  • 39. Intermediaries HTTP
  • 40. Intermediaries App HTTP
  • 41. Intermediaries App HTTP
  • 42. Rack
  • 43. HTTP
  • 44. Intermediaries HTTP
  • 45. Middleware HTTP
  • 46. Middleware App HTTP
  • 47. Rack is the Web
  • 48. The Web is Rack
  • 49. WSGI
  • 50. SPEC
  • 51. lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 52. lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 53. lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 54. lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 55. lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 56. lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 57. lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 58. run lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 59. config.ru
  • 60. $ rackup config.ru
  • 61. $ curl http://localhost:9292
  • 62. Hello
  • 63. class App def call(env) [200, {...}, [...]] end end
  • 64. SPEC
  • 65. $ rake SPEC
  • 66. Rack::Lint
  • 67. lambda { |env| [ 200, { ‘Content-Type’ => ‘text/plain’, ‘Content-Length’ => ‘5’ }, [‘Hello’] ] }
  • 68. env
  • 69. REQUEST_METHOD
  • 70. env[‘REQUEST_METHOD’]
  • 71. GET PUT POST DELETE HEAD OPTIONS TRACE
  • 72. PATH_INFO
  • 73. /items/123
  • 74. HTTP_*
  • 75. HTTP_ACCEPT
  • 76. application/json
  • 77. rack.*
  • 78. rack.input (the input stream)
  • 79. #gets #each #read #rewind
  • 80. yournamespace.*
  • 81. request = Rack::Request.new(env)
  • 82. request.post?
  • 83. request.params[‘id’]
  • 84. request[‘HTTP_IF_MATCH’]
  • 85. m/
  • 86. Middleware App HTTP
  • 87. use MiddlewareA use MiddlewareB use MiddlewareC run app
  • 88. class GoSlower def initialize(app) @app = app end def call(env) sleep(1) @app.call(env) end end
  • 89. class GoSlower def initialize(app) @app = app end def call(env) sleep(1) @app.call(env) end end
  • 90. class GoSlower def initialize(app) @app = app end def call(env) sleep(1) @app.call(env) end end
  • 91. class GoSlower def initialize(app) @app = app end def call(env) sleep(1) @app.call(env) end end
  • 92. class GoSlower def initialize(app) @app = app end def call(env) sleep(1) @app.call(env) end end
  • 93. rack-contrib http://github.com/rack/rack-contrib
  • 94. Rack::Profiler
  • 95. Rack::MailExceptions
  • 96. Rack::JSONP
  • 97. Rack::CSSHTTPRequest
  • 98. Rack::Cache http://github.com/rtomayko/rack-cache
  • 99. Rack::NotFound
  • 100. 404
  • 101. Middleware App HTTP
  • 102. use MiddlewareA use MiddlewareB use MiddlewareC run app
  • 103. class App def call(env) [200, {...}, [...]] end end
  • 104. class GoSlower def initialize(app) @app = app end def call(env) sleep(1) @app.call(env) end end
  • 105. class GoSlower def initialize(app) @app = app end def call(env) sleep(1) @app.call(env) end end
  • 106. use MiddlewareA use MiddlewareB use MiddlewareC run app
  • 107. Middleware App HTTP
  • 108. Middleware App HTTP
  • 109. Cooperative Middleware
  • 110. URI Space
  • 111. /*
  • 112. /just-what-it-needs
  • 113. CloudKit
  • 114. Open Web JSON Appliance
  • 115. expose :notes, :todos
  • 116. expose :notes, :todos
  • 117. contain :notes, :todos
  • 118. use Rack::Pool::Session use CloudKit::OAuthFilter use CloudKit::OpenIDFilter use CloudKit::Service, :collections => [:notes, :todos] (run DefaultApp)
  • 119. CloudKit::OAuthFilter /oauth/*
  • 120. CloudKit::OpenIDFilter /login /logout /openid_complete
  • 121. CloudKit::Service /notes/* /todos/*
  • 122. ?
  • 123. Browser OAuth OpenID Service
  • 124. Browser OAuth OpenID Service
  • 125. Browser {...} OAuth OpenID Service
  • 126. Browser OAuth OpenID Service
  • 127. Browser OAuth OpenID Service {...} Login
  • 128. Browser OAuth OpenID Service
  • 129. Browser OAuth OpenID Service
  • 130. Browser OAuth OpenID Service
  • 131. Service or Desktop App OAuth OpenID Service
  • 132. Service or Desktop App OAuth OpenID Service
  • 133. Service or Desktop App {...} OAuth OpenID Service
  • 134. Service or Desktop App OAuth OpenID Service
  • 135. Service or Desktop App OAuth OpenID Service {...} Login
  • 136. Service or Desktop App OAuth OpenID Service
  • 137. Service or Desktop App OAuth OpenID Service
  • 138. Service or Desktop App OAuth OpenID Service
  • 139. Service or Desktop App OAuth OpenID Service
  • 140. Announcing Middleware Presence
  • 141. HTTP Via
  • 142. Via: 1.0 ricky, 1.1 ethel, 1.1 fred
  • 143. Via: 1.0 ricky, 1.1 ethel, 1.1 fred
  • 144. Via: 1.0 ricky, 1.1 ethel, 1.1 fred
  • 145. Via: 1.0 ricky, 1.1 ethel, 1.1 fred
  • 146. env[‘cloudkit.auth’] = 1
  • 147. env[‘cloudkit.via’] << ‘cloudkit.filter.oauth’
  • 148. env[‘cloudkit.via’] << ‘cloudkit.filter.openid’
  • 149. env[‘cloudkit.user’] = ‘http://joncrosby.me’
  • 150. Alternative Stacks
  • 151. Rack::Map
  • 152. map “/” do run Blog::Public end map “/db” do run Blog::DBAdmin end
  • 153. Rack::Map + Sinatra
  • 154. require ‘sinatra/base’ module Blog class Public < Sinatra::Base get ‘/’ do erb :index end end end
  • 155. require ‘sinatra/base’ module Blog class Public < Sinatra::Base get ‘/’ do erb :index end end end
  • 156. require ‘sinatra/base’ module Blog class Public < Sinatra::Base get ‘/’ do erb :index end end end
  • 157. require ‘sinatra’ for “apps” /* URI space
  • 158. require ‘sinatra/base’ MyClass < Sinatra::Base Minimal Sinatra (routing, rendering, etc.)
  • 159. m/
  • 160. use MySinatraApp run SomeOtherApp
  • 161. Rack::Cascade
  • 162. app1 = lambda { ... } app2 = lambda { ... } run Rack::Cascade.new([app1, app2])
  • 163. Sinatra as Middleware in Rails
  • 164. class X < Sinatra::Base get ‘/what’ do ‘what’ end end Rails::Initializer.run do |config| config.use.middleware ‘X’ end
  • 165. CloudKit in Rails
  • 166. Rails::Initializer.run do |config| config.use.middleware ‘CloudKit::Service’, :collections => [:notes, :todos] end
  • 167. Middleware App HTTP
  • 168. Middleware App Rails HTTP
  • 169. Middleware App Rails Merb HTTP
  • 170. Middleware App Rails Merb * HTTP
  • 171. New Unit of Composition
  • 172. m/