Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rack - A interface por trás dos frameworks web em Ruby

Rack - A interface por trás dos frameworks web em Ruby

34bae1a7ee987164af9d3490ee79f7c9?s=128

Philippe Hardardt

November 17, 2017
Tweet

More Decks by Philippe Hardardt

Other Decks in Programming

Transcript

  1. Rack A interface por trás dos frameworks web em Ruby

  2. Oi, eu sou o Phil

  3. None
  4. O que é Rack?

  5. Ruby Gem

  6. "Uma interface Ruby para webservers”

  7. None
  8. careers.plataformatec.com.br

  9. Servidor de aplicação Aplicação Ruby Navegador GET careers.plataformatec.com.br HTTP Rack

    API P U M A
  10. Mas como é essa interface?

  11. None
  12. None
  13. class MyApp def call(env) status = 200 # ok headers

    = {'Content-Type' => 'text/html'} body = ['<p>Hello Rubyconf!</p>'] [status, headers, body] end end
  14. class MyApp def call(env) status = 200 # ok headers

    = {'Content-Type' => 'text/html'} body = ['<p>Hello Rubyconf!</p>’] [status, headers, body] end end { "HTTP_ACCEPT" => “text/html, ...", "HTTP_USER_AGENT" => "Mozilla/5.0...", "REQUEST_PATH" => "/posts", "REQUEST_METHOD" => "GET", "rack.version" => [1, 3], "rack.request.query_string" => "", "rack.request.query_hash" => {}, "rack.request.cookie_hash" => {} ... }
  15. class MyApp def call(env) status = 200 # ok headers

    = {'Content-Type' => 'text/html'} body = ['<p>Hello Rubyconf!</p>'] [status, headers, body] end end
  16. ~código ao vivo~

  17. Middlewares

  18. Módulos que ajudam a processar uma requisição

  19. Pipeline

  20. None
  21. careers.plataformatec.com.br

  22. M iddlew are 1 M iddlew are 2 M iddlew

    are 3 M iddlew are 4 REQUISIÇÃO RESPOSTA
  23. Com m onLogger M iddlew are 2 M iddlew are

    3 M iddlew are 4 127.0.0.1 - - [07/Nov/2017:00:46:36 -0200] "GET / HTTP/1.1" 200 - 0.0003 127.0.0.1 - - [07/Nov/2017:00:46:41 -0200] "GET / HTTP/1.1" 200 - 0.0003 127.0.0.1 - - [07/Nov/2017:00:46:41 -0200] "GET / HTTP/1.1" 200 - 0.0003 127.0.0.1 - - [07/Nov/2017:00:46:45 -0200] "GET / HTTP/1.1" 200 - 0.0003 127.0.0.1 - - [07/Nov/2017:00:46:55 -0200] "GET /products/2 HTTP/1.1" 200 - 0.0003 127.0.0.1 - - [07/Nov/2017:00:47:02 -0200] "GET /products/2 HTTP/1.1" 200 - 0.0003 127.0.0.1 - - [07/Nov/2017:00:47:04 -0200] "GET /products HTTP/1.1" 200 - 0.0005 127.0.0.1 - - [07/Nov/2017:00:47:05 -0200] "GET /products/1 HTTP/1.1" 200 - 0.0003 127.0.0.1 - - [07/Nov/2017:00:47:07 -0200] "GET /products/3 HTTP/1.1" 200 - 0.0003 127.0.0.1 - - [07/Nov/2017:00:47:09 -0200] "GET /products/2 HTTP/1.1" 200 - 0.0005
  24. M iddlew are 3 M iddlew are 4 a Com

    m onLogger Autenticação 401 UNAUTHORIZED ⛔
  25. class MyMiddleware def initialize(app) @app = app end def call(env)

    # before logic @app.call(env) # after* logic end end
  26. class MyMiddleware def initialize(app) @app = app end def call(env)

    # before logic @app.call(env) # after* logic end end
  27. class MyMiddleware def initialize(app) @app = app end def call(env)

    # before logic @app.call(env) # after* logic end end
  28. class MyMiddleware def initialize(app) @app = app end def call(env)

    # before logic @app.call(env) # after* logic end end
  29. class MyMiddleware def initialize(app) @app = app end def call(env)

    # before logic @app.call(env) # after* logic end end
  30. • Conexão com o banco de dados • Autenticação •

    Telas de erro (exceção) • Rate limit • Controle de cookies • Roteamento • Recarregamento automático de código • Profiling • Arquivos estáticos
  31. Funciona com qualquer framework baseado em Rack ✨

  32. $ rails middleware

  33. use Rack::Sendfile use ActionDispatch::Static use ActionDispatch::Executor use Rack::Runtime use Rack::MethodOverride

    use ActionDispatch::RequestId use ActionDispatch::RemoteIp use Sprockets::Rails::QuietAssets use Rails::Rack::Logger use ActionDispatch::ShowExceptions use WebConsole::Middleware use ActionDispatch::DebugExceptions use ActionDispatch::Reloader use ActionDispatch::Callbacks use ActiveRecord::Migration::CheckPending use ActionDispatch::Cookies ...
  34. None
  35. class ActiveRecord::Migration::CheckPending def initialize(app) @app = app end def call(env)

    # raises error if there are pending migrations ActiveRecord::Migration.check_pending!(connection) @app.call(env) end def connection ActiveRecord::Base.connection end end
  36. class ActiveRecord::Migration::CheckPending def initialize(app) @app = app end def call(env)

    # raises error if there are pending migrations ActiveRecord::Migration.check_pending!(connection) @app.call(env) end def connection ActiveRecord::Base.connection end end
  37. Problemas

  38. Template Streaming (Rails 3)

  39. None
  40. None
  41. Como funciona internamente

  42. class MyApp def call(env) status = 200 # ok headers

    = {'Content-Type' => 'text/html'} body_html = [ 'My e-commerce!’, lazy_view ] [status, headers, body_html] end end
  43. class MyApp def call(env) status = 200 # ok headers

    = {'Content-Type' => 'text/html'} body_html = [ 'My e-commerce!', lazy_view ] [status, headers, body_html] end end
  44. class MyApp def call(env) status = 200 # ok headers

    = {'Content-Type' => 'text/html'} body_html = [ 'My e-commerce!', lazy_view ] [status, headers, body_html] end end
  45. class MyApp def call(env) status = 200 # ok headers

    = {'Content-Type' => 'text/html'} body_html = [ 'My e-commerce!', lazy_view ] [status, headers, body_html] end end
  46. O problema

  47. class DBConnectionMiddleware def call(env) connection = DB.checkout_connection env['db.connection'] = connection

    @app.call(env) ensure DB.checkin_connection connection end end
  48. class DBConnectionMiddleware def call(env) connection = DB.checkout_connection env['db.connection'] = connection

    @app.call(env) ensure DB.checkin_connection connection end end
  49. class DBConnectionMiddleware def call(env) connection = DB.checkout_connection env['db.connection'] = connection

    @app.call(env) ensure DB.checkin_connection connection end end
  50. class DBConnectionMiddleware def call(env) connection = DB.checkout_connection env['db.connection'] = connection

    @app.call(env) ensure DB.checkin_connection connection end end
  51. class DBConnectionMiddleware def call(env) connection = DB.checkout_connection env['db.connection'] = connection

    @app.call(env) ensure DB.checkin_connection connection end end
  52. http://bit.ly/tenderlove_rack_api

  53. http://bit.ly/valim_rack_api

  54. None
  55. A Web está (sempre) mudando

  56. Existem fluxos que fogem do modelo pedido / resposta

  57. Websockets ↔ (Action Cable)

  58. build passou ✅ novo comentário análise de código completa ✅

    GitHub conexão bidirecional
  59. Server push (HTTP/2) ⏩

  60. carreers.plataformatec.com.br index.html logo.png layout.css

  61. class MyApp def call(env) status = 200 # ok headers

    = {'Content-Type' => 'text/html'} body = ['<p>Hello Rubyconf!</p>’] [status, headers, body] end end 1 requisição 1 resposta
  62. None
  63. Rack 3

  64. None
  65. Streams

  66. None
  67. Eventos

  68. ✂ middlewares (Node.js / Connect)

  69. Retrocompatível

  70. Conclusões

  71. None
  72. Conheça o funcionamento das coisas que você usa ⚙

  73. None
  74. Bons exemplos

  75. Entender e resolver problemas

  76. Estamos contratando! http://careers.plataformatec.com.br

  77. Obrigado! peagha @philHenri