[MUSIC] As mentioned in the previous video, a middleware framework is often packaged with web application frameworks. Let's take a look. So middleware frameworks, as we've seen, have been created for connecting web application frameworks, such as Ruby on Rails, to application servers that actually serve up your web application to a web server. Application developers who are building web applications generally don't have to modify the services that are provided in the middleware. Middleware framework APIs are mainly used by those who are actually building the web app frameworks themselves. And generally, the people who build these frameworks don't expose the middleware to the users of the web app framework. So generally, you don't have to play around with this. There are cases of certain applications where you do need to get in and modify the middleware. And I'll show you briefly how to do that in just a moment. Now in Rails, the middleware framework is called Rack, and it's automatically provided for you when you create a Ruby on Rails application. Rack provides a very simple interface that allows web applications to talk to application servers. And what Rack does is it organizes the middleware components into a stack-like structure. And typically, these components are written in Ruby, and you can also specify the dependencies between these components using Rack. And it's actually something called Rack::Builder, which is a domain-specific language that allows you to specify the dependencies and create the stack of components that are in the middleware. Now if you'd like to take a look at the specific middleware components that are provided in a Rails application, just go to the root of the Rails application and type rake middleware. And you'll see a list of all the middleware components that are being used in your web application. When you type rails server, a Rack::Server object is created, and by default, it's attached to WEBrick, and WEBrick, in this case, is acting as both your application and web server. The middleware components are loaded up and made to work with WEBrick, and this is how your application is served up when you go to local host 3000. There are other Ruby web application frameworks that use Rack. One of the most important of these is Sinatra, which is a very lightweight web application framework that doesn't assume active records on the backend. So this is another framework that's quite common for people to use that's built on top of Rack. Let me show you now in more detail what the Rack middleware looks like in a Rails application. So I'm at the root of a rails application, the blog application in this case. And if we type rake middleware, we can see all of the middleware components. And so, the initial component, this is the top of the stack, and what happens is the request that's received from the browser proceeds through this stack until the very last component, which is called the blog application routes. So this actually routes the request to a particular controller within your application. Now you'll notice that ActionDispatch is a module that's used quite heavily throughout the middleware. So once again, the request works its way down to this very last call and then back up again in order to return a response to the browser. Let me show you how to create a really simple piece of middleware and add it to this middleware. Now this is an example I found on the Internet. It's a toy example, it's very, very simple. So let's start by creating some code, and I'm going to call it a timer. So I'll create a middleware component that allows us to time how long it takes for a request to be received and then a response returned to the browser, so basically the amount of time it takes to work through the middleware, actually interact with our application, and then return a response to the server. So, I've created this class called Timer, and I've put it under live. So there's a timer.rb, and there's two main things that you need to do if you're going to create a middleware component. The first thing is you need to have a function called initialize, and this initialize function simply takes an app as input. So we're going to pass a Rails app or a Sinatra app. In our case, this'll be the Rails app itself. And then you actually call with an environment provided as the input to this function call. And the way this works is you implement on the app another call function. So this is the recursive sets of calls that gets you through that middleware stack. And then what gets returned is a status of the middleware, headers, and a response, and this is actually what gets returned to the client as well eventually. So these are the only two things that we really need to get this set up. These are the required parts. The initialize method takes an application and then the call method takes an environment. Initialize sets things up, and the call is what happens when a request comes in. So let's add some pieces to this. I'm going to start a timer. I'm going to create a variable called start that reads a timer. We're going to make the call, and then we're going to stop. Create a variable called stop that reads the timer again, and then we'll compare the two. And so we're going to take stop- start, and then we're going to change this to a string, and then I'm going to return it as a header. So this is going to end up in the header field in our response, and I'll show this to you when we actually make this call. Now lastly, we have to return because, again, this is in a stack, so we have to return the status header's response to whatever call this function. So, this is what's returned to the call function that called this function, and this is how it works, the status headers and response work its way down and then back up again. So this is this timer function that I'd like to include in our middleware. And the way you include it in the middleware is you can go to config and application.rb. And I'm going to add, first of all, we need to read this file in, so under live timer, we're going to go ahead and read this file in at this point. And then I'm going to add to the middleware, so I'm going to say config.middleware.insert_before, and the very first thing in our middleware was called Sendfile. And so, before that, I'm going to insert the middleware thing that I just created, this middleware component that I just created called Timer. So let's go ahead and run this, and I'll show you rake middleware, and you'll see that this new middleware component is now in the rack middleware that our application is going to use. So now when we type rake middleware, we'll see that the very first component in the middleware is our timer, so again, we're going to start the clock, we're going to take a reading from the clock essentially here. We're going to process this request, it's going to get routed to our application, the application will process the request, work its way back up, then we set the stop variable by again reading the timer. And then, in a header, I'm placing the result of this timing. How long did this request take? Let's take a look. First of all, we're going to have to start the application running. So we'll do rails s, start the application running. And again, I want to point out that WEBrick is being used here. And then, this is the call that starts the HTTP server running on port 3000. Let's go to that port and make a request in our app. So I've opened up a browser. And for whatever browser you're using, open up the developer tool. So I'm using Web Inspector and Safari, and I'm going to go ahead and execute a request. I'm just going to go to localhost 3000, and if I select this, go over here, and from within whatever tools you're using, find the response headers. And if you look under the response header, you're going to see this x timing, and this is the amount of time it took to process that request. Now you'll notice that this browser framework provides its own timing that's almost identical to what we did, so it's probably placed some place else. It's not in the middleware framework, but part of the browser itself, I think. But anyways, we've done it as a part of the middleware framework. This is a really straightforward example that I gave you. I just want to show you that you can in fact interact with the middleware and add your own middleware component, and that it's real. I don't expect you to actually do this that very often when you build web apps. Let me go ahead and make another request. Let's go to post and, again, you need to select the request that was made. Look at the response headers, and you should see, again, x timing. This one took a bit more time because it had to actually read the database to pull that post out. So again, just a very simple example of how you can add a middleware component to the Rack framework as part of a Ruby on Rails web application.