Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Rack in Rails

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 351
    Comment on it

    Rack is a middleware, it provides an interface for a web server to interact with a web application. To understand how rack is used to interact with web server and rack(rails) application, lets first understand the request-response cycle. Client requests a page from server. Web server receives the request but it does not know what to respond. It sends the request to rack middleware. Web server does not need to interact with the rails application. Rack understand the web server request and send it to application. Our application understands rack requests so it respond with required information. Rack send it back to web server, which server handles to respond to the client.


    A Rack application is any ruby object that can respond to call method. An env variable is passed to the call method.

     

    Server converts the HTTP request to a simple Ruby Hash and passes it to middleware, as shown below:

    env = {
      'REQUEST_METHOD' => 'GET',
      'PATH_INFO' => '/users',
      'HTTP_VERSION' => '1.1',
      'HTTP_HOST' => 'localhost',
      ...
      ...
    }

     

    The return from the call method should be an array of 3 items:

    HTTP status code (200, 302, etc...)
    A Hash of headers
    Response body


    The server takes this array and convert it into a valid HTTP response and send it to the client.

     

    Lets create a simple rack application. We create a class and define a class method call, which takes an argument env. Also the method returns and array of 3 items we discussed above. On the top of our file we require "rack".
     

    require 'rack'
    
    class MyApp
      def self.call(env)
        [
          200,
          {'Content-Type' => 'text/html' },
          [ "<html>", "<h1>Hello our rack app is ready</h1>", "</html>" ]
        ]
      end
    end

     

    Now we can call rack app in two ways:

    1. Name the file with extension .ru(rack up), which denotes it is a rack file. In our file add a line:  run MyApp


       Now when we call rackup MyApp.ru. You will see something like this in console:

      Thin web server (v1.6.3 codename Protein Powder)
      Maximum connections set to 1024
      Listening on localhost:9292, CTRL+C to stop
      127.0.0.1 - - [18/Apr/2016:19:05:53 +0530] "GET / HTTP/1.1" 200 - 0.0008
      127.0.0.1 - - [18/Apr/2016:19:05:53 +0530] "GET /favicon.ico HTTP/1.1" 200 - 0.0005

    Now you can access the output in browser with url localhost:9292


    2. We can add a line to file:
       Rack::Handler::WEBrick.run MyApp
       
       Now in console we can call a like a ruby file: ruby myApp.rb
       The Webrick server will start our application and you will see output like this:

      [2016-04-18 19:15:35] INFO  WEBrick 1.3.1
      [2016-04-18 19:15:35] INFO  ruby 2.2.1 (2015-02-26) [x86_64-linux]
      [2016-04-18 19:15:35] INFO  WEBrick::HTTPServer#start: pid=4287 port=8080

      Now we can access our app at localhost:8080

     

    We can also write our own middleware and use in out application. Lets create our middleware. All Middleware classes have an initialize method that takes an application as an argument. Also we have a call method that takes an environment hash variable as an argument. The call method in our middleware invokes the class method call of our MyApp app. Which returns an array.


    The whole file (myApp.rb) look like this:

    require 'rack'
    
    class MyApp
      def self.call(env)
        [
          200,
          {'Content-Type' => 'text/html' },
          [ "<html>", "<h1>Hello our rack app is ready</h1>", "</html>" ]
        ]
      end
    end
    
    class MyMiddleware
      def initialize(app)
        @app = app
      end
    
      def call(env)
        puts "**calling our middleware**"
        status, headers, response = @app.call(env)
        [status, headers, response]
      end
    end
    
    app = Rack::Builder.new do
      use MyMiddleware
      run MyApp
    end
    
    Rack::Handler::WEBrick.run app
    


    Now you can run the app and see the output in the browser. Also you can see the line we print ("**calling our middleware**") inside call method that indicate our middleware is being used.

     

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: