8. Request is a…
• It is set of instructions that tells a server what
kind of response we want.
• It is a part of HTTP (request/response) protocol.
• HTTP uses one of the verbs like GET, POST, PUT
& DELETE when you perform the request to the
server.
13. What is a Web Server?
• Web Server is strictly HTTP based, it just takes
HTTP requests and sends back HTTP responses
to the clients(browsers).
• It is mostly designed to serve static files.
• It also has other functionality like request
pipeline, load balancing etc. App servers lack
these functionalities.
• E.g. Ngnix, Apache
15. What is an App Server?
• App Server actually runs your Rails app.
• App Server is mostly known for to serve dynamic
pages.
• E.g. Webrick, Passenger, Mongrel, Unicorn, Thin,
Puma & etc.
16. Request to Rails app
• Rails isn’t just one application, it has lots of
independent Rack applications (middlewares).
• When request comes to the Rails app, it goes
through the list of middleware series.
• Last part of that series, sends request to the
routes file.
17. Request to Rails app
• Based on request, Rails decides which controller
& action need to be executed from the routes file.
• After executing the controller’s action, Rails sends
back response to the the client.
• Web Server & App Server actually handle the job
of sending response back to the proper client.
19. What is a Middleware?
• Middleware is a Rack application.
• Middleware is basically a filter for request and
response.
20. Rails Middlewares
App
Server
Rails App
A B C D
Routes
Controller
Models
Views
Here A, B, C & D are middlewares
Each of these does processing on request & response
21. Why Rails uses Middlewares?
• Before rails 3, Rails was very tightly coupled.
• As Rails was growing, apps built on Rails had more
demanding requirements. For some apps, Rails gave
lots of additional stuffs by default, which was not
required like cookies/flash. For some other apps, to
implement new filter on the the request/response was
not possible.
• In Rails 3 and after, all these issues have got solved by
using a concept of Rack.
23. What is a Rack?
• Rack is not Rake.
• Rack is simple but powerful spec. Yes it is just
spec.
• It is not web framework or web server.
• Rack is created by Christian Neukirchen
24. Rack - Just an Interface
• It is an interface that sits between your web/app
server and your application. It wraps HTTP
requests and responses in the simplest way
possible, it unifies and distills the API for web
servers, web frameworks and software in
between (i.e. middleware) into a single method
call.
25. Rack Specification
• Specification: A Rack application is a Ruby object
(not a class) that responds to `call`. It takes
exactly one argument, the environment and
returns an Array of three values, The status, the
headers, and the body. That’s it.
26. Why do we need Rack?
• Rack promotes low coupling.
• If there was’t Rack, then each framework had to
add separate handler for Thin, Mongrel, Unicorn
and etc to run the app on these servers.
• In reality it’s not a job of framework. They should
not need to take care of it.
30. Using Middleware in a Rack app
• Using ‘use’ method of Rack, you can use
middleware component in Rack application.
• You can use multiple middleware components
which help to change request/response as you
need.
• You can add middlewares by using two methods.
By directly adding middleware in config.ru
and using Rack::Builder.
34. What is Rack::Builder?
• Rack::Builder implements a small DSL to
iteratively construct Rack applications.
• Rack::Builder is the thing that glues Rack
middlewares and application together and
converts them into single entity/rack application.
• Under the hood, ‘rackup’ command converts
your config.ru script to an instance of
Rack::Builder.
37. Rails on Rack
• Rails application is the primary Rack
application object.
• It has ‘call’ method similar to rack’s ‘call’
method in its source code (i.e. in
Rails::Application).
38. Rails’ Rack::Builder
• Same like Rack::Builder, we have similar
concept in Rails, it is called as
ActionDispatch::MiddlewareStack.
• Better flexibility and more features to meet Rails’
requirement.
39. Rails’ Rack::Builder
• Rails::Application uses
ActionDispatch::MiddlewareStack to
combine various internal and external
middlewares to form a complete Rails Rack
application.
40. Inspecting Rails Middlewares
• Rails provides a task for inspecting the
middleware stack in use.
• $ bin/rake middleware
42. Using Middleware in Rails
• Rails provides a simple configuration interface
config.middleware for adding, removing and
modifying the middlewares in the middleware stack via
application.rb or the environment specific configuration
file environments/<environment>.rb.
• Using these methods config.middleware.use,
config.middleware.insert_before,
config.middleware.insert_after, you can add
new middleware to the middleware stack.
• It also provides ‘swap’ and ‘delete’ methods for
swapping and deleting a middleware.
43. Add this file under config/initializers directory
And under config/application.rb file, add this following line
config.middleware.use "SayHelloMiddlware"
44. Always Remember That…
• When request comes to your Rails app, it goes
through these middlewares. From top to bottom.
• At the bottom, request enters into the your Rails’
MVC area.
In simple way, when we hit any url in the browser for some file, that browser converts that url into the request message and sends to the server and that request message is your actual request :)
When you want to get some data from the server, you use GET method.
When we want to create new data on the server, we use POST method.
When we want to update data like username we use PUT method.
For destroying the data we use DELETE verb.
There are also other methods like, HEAD, PATCH, OPTIONS, CONNECT & ETC which HTTP protocol provides.
This is a basic and standard diagram of Rails Request Life Cycle.
You can see here, When browser initiates the requests it goes to Web Server, From the Web Server It goes through the App server, From App Server, request enters into the Rails app.
Now if you see in the Rails app, request goes through the series of middlewares, From there request goes to the routes file and Based on request, Rails decides which controller & action need to be executed from the routes file. Now in controller if there is any business logic, it goes to model and from there it will fetch data from database or store the data in the database.
If there any view like html, then request goes to view. After processing it, controller sends back the response to Browser.
In this diagram, I’m showing how app server and rails app communicate with each other.
Communications between App Server and Rails app happen using Rack. Rack is a gem and acts as an interface between them. We will see more on rack in next slides.
It recognises Ruby application request and then it forwards its request to app server.
Web Server forwards its request to the App Server, and App Server in turn forwards that request to the Rails app.
In development mode, App Server can play role of web server too. In production it does not scale too much so we need web server in between.
This is all about basics of Rails request life cycle.
Now lets see how rails handles the request under the hood.
You can think of middlewares isolate the different stages of processing on the request and response.
One of the best things of Rack, you customise request/response very easily, by chaining middleware components in between the app server and the rails app.
Before Rails 3, handling of session, parsing for parameters and etc were too difficult.
Rake is “Make for Ruby” and it is task runner for Ruby.
Argument environment is nothing but environmental variables hash like PATH_INFO, QURY_STRING, REMOTE_ADDR, REQUEST_URI and all that junk.
You can say this environment variable has all information of the request.
Using low coupling, you can replace any component with another one without having to reimplement code.
Here is a simple example of rack application.
This is another way to write rack application using rackup command which is given by Rack. The only thing you need is, to write your code in config.ru and run it using rackup config.ru.
In this code, I have defined rack application using MyRackApp and I have defined one middleware using MyMiddleware class.
When you want to apply middleware to your rack application you have use ‘use’ method of Rack.
When request comes, it comes from top to bottom. Means from the middleware to the actual rack application.
Always remember that, middleware’s initialize method always takes an argument i.e. app that app is nothing but your next middleware or next rack application.
Think of Rack::Builder object as stack in which your actual rack application is at bottom and all middlewares on top of it. The whole stack you can call it as rack application too.
Many of Action Dispatcher’s internal components are implemented as Rack middleware.
You can inspect middleware stack of your rails application by using
This list is quite big, So I’m not going to explain what each of these middleware does here. But there is one middleware, I think most of you have seen it, that is CheckPending.
Anyone knows what it does?
Lets write one middleware in the rails app.
I mostly prefer to write middleware in config/initializers folder.
In this middleware, mostly in call method, if request_path is ‘say_hello’, then this middleware will send this response back to the client.
So here, our rails app will get called.
If request_path ‘say_hello’ then our rails app gets called.
To add this middleware in rails’s middleware stack, we need to set middleware to config.middleware.use or….config.middleware.insert_after
But when we use this config.middleware.use then that middleware will get applied at the bottom of rails middleware series.