SlideShare une entreprise Scribd logo
1  sur  63
Télécharger pour lire hors ligne
Building web framework
       with Rack
          Marcin Kulik


       EuRuKo, 2010/05/30
I am:
Senior developer @ Lunar Logic Polska -
agile Ruby on Rails development services

Working with web for 10 years

Using Ruby, Python, Java and others - in
love with Ruby since 2006
Open Source contributor:
 CodeRack.org - Rack middleware
 repository

 Open File Fast - Netbeans and JEdit
 plugin

 racksh - console for Rack apps

 and many more (check
 github.com/sickill)
Why would you need
   another framework?
"Because world needs yet another framework ;-)" - Tomash
No, you probably don't need
       it actually :)
Several mature frameworks

Tens of custom/experimental ones

"Don't reinvent the wheel", right?

But...
But it's so easy that you
  should at least try
Rack provides everything you'll need, is
extremely simple but extremely
powerful

It will help you to better understand
HTTP

It will make you better developer

Your custom framework will be the
fastest one *

It's fun! A lot of fun :)
What is Rack?
Ruby web applications interface

library
Simplest Rack application
run lambda do |env|
  [200, { "Content-type" => "text/plain" }, ["Hello"]]
end
Simplest Rack middleware
class EurukoMiddleware
  def initialize(app)
    @app = app
  end
  def call(env)
    env['euruko'] = 2010
    @app.call
  end
end
Let's transform it into
      framework!
How does typical web
framework look like?
Rails

Merb

Pylons

Django

Rango
Looks like MVC, more or less
What features we'd like to
         have?
dependencies management
RESTful routing
controllers (session, flash messages)
views (layouts, templates, partials)
ORM
authentication
testing
console
Available Rack middleware
   and tools we can use
(1/8) Gem dependency
     management
bundler
  "A gem to bundle gems"

github.com/carlhuda/bundler
# Gemfile
source "http://gemcutter.org"
gem "rack"
# config.ru

require "bundler"
Bundler.setup
Bundler.require
(2/8) Routing
Usher
"Pure ruby general purpose router with interfaces for rails, rack,
              email or choose your own adventure"

                  github.com/joshbuddy/usher
# Gemfile

gem "usher"
# config.ru
require APP_ROOT / "config" / "router.rb"

run Foobar::Router
# config/router.rb
module Foobar
  Router = Usher::Interface.for(:rack) do
    get('/').to(HomeController.action(:welcome)).name(:root) # root
    add('/login').to(SessionController.action(:login)).name(:login)
    get('/logout').to(SessionController.action(:logout)).name(:logo
    ...
    default ExceptionsController.action(:not_found) # 404
  end
end
(3/8) Controller
Let's build our base
       controller
every action is valid Rack endpoint

value returned from action becomes
body of the response
# lib/base_controller.rb

module Foobar
  class BaseController
    def call(env)
      @request = Rack::Request.new(env)
      @response = Rack::Response.new
      resp_text = self.send(env['x-rack.action-name'])
      @response.write(resp_text)
      @response.finish
    end
    def self.action(name)
      lambda do |env|
        env['x-rack.action-name'] = name
        self.new.call(env)
      end
    end
  end
end
# config.ru
require APP_ROOT / "lib" / "base_controller.rb"
Dir[APP_ROOT / "app" / "controllers" / "*.rb"].each do |f|
  require f
end
Now we can create
 UsersController
# app/controllers/users_controller.rb
class UsersController < Foobar::BaseController
  def index
    "Hello there!"
  end
end
Controllers also need following:
 session access

 setting flash messages

 setting HTTP headers
 redirects

 url generation
rack-contrib
  "Contributed Rack Middleware and Utilities"
         github.com/rack/rack-contrib


            rack-flash
"Simple flash hash implementation for Rack apps"

        nakajima.github.com/rack-flash
# Gemfile
gem "rack-flash"
gem "rack-contrib", :require => 'rack/contrib'
# config.ru

use   Rack::Flash
use   Rack::Session::Cookie
use   Rack::MethodOverride
use   Rack::NestedParams
# lib/base_controller.rb

module Foobar
  class BaseController
    def status=(code); @response.status = code; end
   def headers; @response.header; end
   def session; @request.env['rack.session']; end

   def flash; @request.env['x-rack.flash']; end
   def url(name, opts={}); Router.generate(name, opts); end
    def redirect_to(url)
      self.status = 302
      headers["Location"] = url
      "You're being redirected"
    end
  end
end
Now we can use #session,
 #flash and #redirect_to
# app/controllers/users_controller.rb

class UsersController < Foobar::BaseController
  def openid
    if session["openid.url"]
      flash[:notice] = "Cool!"
      redirect_to "/cool"
    else
      render
    end
  end
end
(4/8) Views
Tilt
"Generic interface to multiple Ruby template engines"

             github.com/rtomayko/tilt
# Gemfile
gem "tilt"
# lib/base_controller.rb

module Foobar
  class BaseController
    def render(template=nil)
      template ||= @request.env['x-rack.action-name']
      views_path = "#{APP_ROOT}/app/views"
      template_path =
        "#{views_path}/#{self.class.to_s.underscore}/" +
          "#{template}.html.erb"
      layout_path =
        "#{views_path}/layouts/application.html.erb"
      Tilt.new(layout_path).render(self) do
        Tilt.new(template_path).render(self)
      end
    end
  end
end
(5/8) ORM
DataMapper
"DataMapper is a Object Relational Mapper written in Ruby. The
 goal is to create an ORM which is fast, thread-safe and feature
                             rich."

                        datamapper.org
# Gemfile

gem "dm-core"
gem "dm-..."
# app/models/user.rb

class User
  include DataMapper::Resource

  property :id, Serial
  property :login, String, :required => true
  property :password, String, :required => true
end
# config.ru
Dir[APP_ROOT / "app" / "models" / "*.rb"].each do |f|
  require f
end
(6/8) Authentication
Warden
"General Rack Authentication Framework"

      github.com/hassox/warden
# Gemfile

gem "warden"
# config.ru
use Warden::Manager do |manager|
  manager.default_strategies :password
  manager.failure_app =
    ExceptionsController.action(:unauthenticated)
end
require "#{APP_ROOT}/lib/warden.rb"
# lib/warden.rb
Warden::Manager.serialize_into_session do |user|
  user.id
end
Warden::Manager.serialize_from_session do |key|
  User.get(key)
end
Warden::Strategies.add(:password) do
  def authenticate!
    u = User.authenticate(
          params["username"],
          params["password"]
        )
    u.nil? ? fail!("Could not log in") : success!(u)
  end
end
# lib/base_controller.rb
module Foobar
  class BaseController
    def authenticate!
      @request.env['warden'].authenticate!
    end
   def logout!(scope=nil)
     @request.env['warden'].logout(scope)
   end
    def current_user
      @request.env['warden'].user
    end
  end
end
Now we can guard our action:
# app/controllers/users_controller.rb
class UsersController < Foobar::BaseController
  def index
    authenticate!
    @users = User.all(:id.not => current_user.id)
    render
  end
end
(7/8) Testing
rack-test
"Rack::Test is a small, simple testing API for Rack apps. It can be
     used on its own or as a reusable starting point for Web
         frameworks and testing libraries to build on."

                  github.com/brynary/rack-test
# Gemfile
gem "rack-test"
require "rack/test"

class UsersControllerTest < Test::Unit::TestCase
  include Rack::Test::Methods
 def app
   Foobar::Router.new
 end

 def test_redirect_from_old_dashboard
   get "/old_dashboard"
   follow_redirect!
    assert_equal "http://example.org/new_dashboard",
                 last_request.url
    assert last_response.ok?
  end
end
(8/8) Console
racksh (aka Rack::Shell)
 "racksh is a console for Rack based ruby web applications. It's
like Rails script/console or Merb's merb -i, but for any app built
                             on Rack"

                   github.com/sickill/racksh
Installation
gem install racksh
Example racksh session
$ racksh
Rack::Shell v0.9.7 started in development environment.
>> $rack.get "/"
=> #<Rack::MockResponse:0xb68fa7bc @body="<html>...",
   @headers={"Content-Type"=>"text/html", "Content-Length"=>"1812"}
   @status=200, ...
>> User.count
=> 123
Questions?
That's it!
Example code available at: github.com/sickill/example-rack-
                        framework

email: marcin.kulik at gmail.com / www: ku1ik.com / twitter:
                            @sickill

Contenu connexe

Tendances

Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparison
Hiroshi Nakamura
 
Ruby on Rails Security
Ruby on Rails SecurityRuby on Rails Security
Ruby on Rails Security
amiable_indian
 

Tendances (20)

HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
 
A Toda Maquina Con Ruby on Rails
A Toda Maquina Con Ruby on RailsA Toda Maquina Con Ruby on Rails
A Toda Maquina Con Ruby on Rails
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparison
 
Sinatra Rack And Middleware
Sinatra Rack And MiddlewareSinatra Rack And Middleware
Sinatra Rack And Middleware
 
CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009
 
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...
 
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
 
Nodejs.meetup
Nodejs.meetupNodejs.meetup
Nodejs.meetup
 
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other ToolsCool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
WP Weekend #2 - Corcel, aneb WordPress přes Laravel
WP Weekend #2 - Corcel, aneb WordPress přes LaravelWP Weekend #2 - Corcel, aneb WordPress přes Laravel
WP Weekend #2 - Corcel, aneb WordPress přes Laravel
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
BP-6 Repository Customization Best Practices
BP-6 Repository Customization Best PracticesBP-6 Repository Customization Best Practices
BP-6 Repository Customization Best Practices
 
Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3
 
Beyond Phoenix
Beyond PhoenixBeyond Phoenix
Beyond Phoenix
 
Ruby on Rails Security
Ruby on Rails SecurityRuby on Rails Security
Ruby on Rails Security
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Intro to Rack
Intro to RackIntro to Rack
Intro to Rack
 
Mastering Grunt
Mastering GruntMastering Grunt
Mastering Grunt
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 

Similaire à Building web framework with Rack

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
Nick Sieger
 
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
Ben Lin
 
Red5workshop 090619073420-phpapp02
Red5workshop 090619073420-phpapp02Red5workshop 090619073420-phpapp02
Red5workshop 090619073420-phpapp02
arghya007
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
旻琦 潘
 

Similaire à Building web framework with Rack (20)

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011
 
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
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular application
 
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...TorqueBox: The beauty of Ruby with the power of JBoss.  Presented at Devnexus...
TorqueBox: The beauty of Ruby with the power of JBoss. Presented at Devnexus...
 
Ruby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developerRuby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developer
 
Rack
RackRack
Rack
 
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
 
Connecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRubyConnecting the Worlds of Java and Ruby with JRuby
Connecting the Worlds of Java and Ruby with JRuby
 
Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!Rapid Prototyping FTW!!!
Rapid Prototyping FTW!!!
 
Red5workshop 090619073420-phpapp02
Red5workshop 090619073420-phpapp02Red5workshop 090619073420-phpapp02
Red5workshop 090619073420-phpapp02
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Ruby on Rails - Introduction
Ruby on Rails - IntroductionRuby on Rails - Introduction
Ruby on Rails - Introduction
 
Rack
RackRack
Rack
 
Supa fast Ruby + Rails
Supa fast Ruby + RailsSupa fast Ruby + Rails
Supa fast Ruby + Rails
 
RoR guide_p1
RoR guide_p1RoR guide_p1
RoR guide_p1
 
Dev streams2
Dev streams2Dev streams2
Dev streams2
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发
 
Knolx session
Knolx sessionKnolx session
Knolx session
 
RoR 101: Session 2
RoR 101: Session 2RoR 101: Session 2
RoR 101: Session 2
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Dernier (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 

Building web framework with Rack