Rack Middleware

4,131 views
4,014 views

Published on

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,131
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
58
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Rack Middleware

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

×