 Okay, so just a little introduction because I've got a lot to get through and I don't want to spend Very much time on myself. My name is Michael Jackson. I I'm still alive. I Yeah, everybody's telling me like dude I thought you died so I am originally from California but I live here now in Utah I Work as an independent Ruby contractor web developer. I do a lot of Web development work just JavaScript CSS HTML whatever Today I want to talk About a library called rack now. I've only been really using Ruby for about about two years and That's kind of the same time not really but it's kind of the same time that rack Came on the scene and people were like whoa, and I was like whoa because I came from PHP background and Roll your eyes now. Okay, and yeah, seriously, and I was like, whoa, what is this rack and and what was crazy was everybody? Started like putting their libraries on rack, you know like the rails guys are like hey We should use rack and and the Sinatra guys are like we're using rack and and the thin developer was like I'm Then is we're rack and I was like what the heck is rack? And you know, I I was actually talking to a developer friend of mine Last year and he was he was developing an app and rails and he's like all rails to three is on rack And he was like now I got to learn rack and as well as rails, you know And I was like you don't have to learn rack like it all just works for you, you know, but but I think his comment kind of typified Unfortunately the feeling that I've heard from a few other people to like what is this rack thing? You know, what is this library like a lot of people are talking about it? But what does it do? Why is it necessary? You know, what what what what do we what are we using it for? And so the my talk today The the reason that I think it's important is because it has seriously Changed the way that That we write for the web in Ruby. Let me see just by a show of hands real quick I promise is the only time I'll make you raise your hand. How many people are using Ruby to do web web servers web frameworks web Services, that's like everybody in here. Okay, they're like five people not raising their hands Everybody is using Ruby to do web What's so cool about The Ruby web development community and you realize this if you come from another background is that you can write Stuff in Ruby like you can just you can just take all of these different servers and frameworks and libraries and middlewares and you can like Stick them all together, you know, like in some big hodgepodge and it's it's it's kind of weird because you know another language is if If you're a PHP developer, for example, okay? What are you gonna do if you're gonna write a web app? You're gonna be like, okay? We're gonna use Drupal or we're gonna use I don't know. What are the PHP? Cake or something yeah, and and so it's like We will use the framework do not go outside The framework, you know and we are running it on Apache on mod PHP. That's it and and you know some dudes like hey Let's run it on you know fast CGI no Because I don't know it might be different on fast CGI, you know, we might have some different environment variables So you just you know, we're running it on mod PHP. We're running it on Apache and it's like it's it's very strict sort of you know Way to develop and deploy your apps and then you come to the to the ruby world and it's like Hey, you know, what do you want to write your app in? I don't know we could write it in rails We could write it in Sinatra. We could write it in MIRB Well, not anymore because MIRB got the axe, but I don't know. Did he get the axe? I don't know still live Anyway, and then well how we're gonna deploy it. I don't know we could like do it on Longroll or we could run it On passenger we could run it on thin Okay, so basically I'm gonna take this down. Is that okay cuz I want to be oh Snap there is I'm kind of a wired guy, but I'll try this wireless thing Hello, hello. Oh Yeah, it's good. I'm wife nice So anyway, it's just what I'm saying we got lots of ways to write web apps, right? We can write on however we want we've got lots of ways to serve web apps Does that ever strike you is kind of like wow? How do they how do they all work together, you know? I mean how how is it possible that I can take a rails app and I can deploy it on any number of application servers but I can I can take a Sinatra app and I can run it on all those servers as well Like I can basically write it for any framework and run it on any server that I want It's it's actually pretty amazing Here's here's kind of like how I how I picture it right along the top here You've got all your different ways to serve web apps, right? You've got CGI or FC GI And then you've got things like You know passenger which is you know an engine X or Apache module and then you've got your different app servers Which are pretty popular and obviously this is not a comprehensive list right there are lots more along the bottom You've got all your different frameworks, right? These are all the different ways you can write an app in rails or Sinatra Camping or MIRB or Ramazze Ramaze. I'm not sure how to pronounce so in Back in the early days The people who are writing rails are like, okay How are we gonna run our rails out? I don't know let's run over CGI Okay, so if you were writing a rails app like before 2 3 you had a little file in your public directory called dispatch dot CGI Anybody familiar? Oh, sorry. I told you I wouldn't raise your hands. No, put it down And then there was another file called dispatch dot FC GI right And then so if and then Mongo came along and it was like, okay So there's a mongrel command and then there's a mongrel underscore rails command, right? So you see the coupling that was happening you have you have a specific adapter for rails And all these and and and you know an adapter for rails and CGI an adapter for rails and FC GI a Specific layer of software for rails on mongrel Finn had has a rails adapter, you know, so it can detect if it's being run from inside a rails directory So you've got these couplings that are going on And so, you know, that's kind of represented by these arrows any anytime you want to run rails on Any one of these different servers you've got you've got a little coupling there. It might be small, right? It's a small thing, but there is still a little bit of coupling going on So if you kind of do the math you follow the pattern you've got, you know Anytime you want to write a web app anytime you want to you write a framework If you want to run it on all the different servers You have to figure out how do you're going to run it on all those different servers, right? This is stuff that like you don't you don't ever think about if you code PHP because it's just like Yeah, we're gonna run on Apache and mod PHP like duh. Why would we do anything else, right? but it changes when you've got a language like ruby and and It it it wasn't like written for the web, you know, just people are using it for the web, right? So so it's a mess You need The common kind of language here, and that's rack. Okay rack is basically it's a It's a library that has an interface it specifies an interface For servers and frameworks, right? So this is this says this is how you talk to one another Okay, so you don't have to worry about rails You don't have to worry about what app server you're running on anymore You are a rack app and the same for you Sinatra and the same for you all your frameworks You are rack apps and then you can run on any framework you want, right? And then I can write some middleware, and I can be like, yeah, you know, I I I just wrote some really cool middleware. Well, cool. How am I gonna use it? Well, you can use it with any anything that's rack compatible Right, so I can have I can have a piece of middleware, and I I'm writing a rails app And I'm like that's a really cool middleware, and we'll get into middleware. Don't worry about it If this is going over your head, we'll we'll talk about what is middleware, right? So it you know everybody talks to rack and rack handles the translation That's a pretty huge thing. Well, how do they how do they know? There's a spec Duh, it's like a spec. Oh my gosh revolutionary. It takes you like five minutes to read this spec. It is so small If you are developing for the web Hello, if you're developing for the web You need to go read the spec Do yourself a favor go read the spec Because no matter how you're writing stuff for the web you are using rack nowadays unless you're just like straight-up writing XML files pumping them through rake and Like sprinkling excess LT on them and making a little website like if you have anything that's any Application logic on the server you're running on rack So follow the spec Let's let's talk about it. What is the spec? This is the spec in a nutshell. Okay, you've got it basically specifies three things You've got an environment. What is an environment? It's a hash. What is it? What does a hash have it has keys and values the keys are like HTTP? CGI like headers, right? So like I don't know HTTP host You know path info query string, you know these types of things that you get In the in your CGI environment, and then you've got a couple of a couple of variables in that environment that rack throws in there as Well, it's all in the spec like I said, it's real simple real straightforward They've you've got apps Okay, an app. What is it? It's an object response to one method. I mean you can't get any simpler response to one method call Takes one parameter The aforementioned hash, right? What does it return? It returns an array three elements in the array status headers body The genius about rack is that it is so simple to implement. It's not like You know It's not like some book, you know, I mean everybody's like, yeah, we could do that. That's easy Like we could totally be rat compatible, you know, and and and you'll see it actually We're gonna look at like some of the rails source code later You've got like like in the rails three which by the way I know some of the authors are here and they've done a fantastic job with it You go and you check it out and it's it's all just like it's all middleware Like Because it's it all you need to have is a method in there that takes a hash, you know I might not be making sense But this is kind of a this is kind of an example of what that hash looks like Okay, this is kind of what your environment looks like. Okay, if you have developed in in other environments and you're coming to Ruby You will realize the significance of this hash. It's it's awesome that you can always count on those Values being there and being written in the same way no matter what environment you're running in. Okay, this is your environment hash This is this is like an app that's like a like super simple. So the top right a lambda It's got a call method Right. So a lambda is a valid rack app You could run that you could fire up this rack app and we're going to I'm going to show you how we kind of run it You could fire that thing up and you could you could Just serve hello world all day people would love you Or you know, you could instantiate a little object here, right? We've got a little class It's got a little method called call boom instantiate it and all of a sudden it's a valid rack app, right? These are just kind of you know real simple examples. I keep talking about middleware. What is middleware? Middleware really is the lifeblood of the rack ecosystem. Go to github search for rack. You'll get like I Think it's I think it's all up to almost 500 repositories, okay, you know The manual stuff That you kind of have to do like every time you write a web app, you know like how are we gonna do sessions? You know, how are we gonna do cookies? How are we gonna do? I don't know Jason to the client. How are we gonna do? Detect if it's a mobile client like like monotonous stuff It's it's all just middleware and I'm gonna show you how it works So middleware is like a fancy. It's like a fancy app. It's got one more method, right? It's got an initialized method When when middleware is invoked it's inserted into the pipeline. I'll show you how that happens It takes an instance of the app in its initialized method case This is kind of a generic template for a middleware stores the instance of the app, right internally and then later on when you call it All it's got to do is it's got to say app. I'm calling you So it just it just passes the environment right through right so you can have a chain You can they like wrap one another, right? So it's like your app is at the core and then you've got all these middlewares that are just wrapping it, right? and when one of them gets called the the They just pass the environment all the way down to your app That's at the very core of the right and then it it will return the array, right? Just like the spec says status headers body Returns the array and it returns it to the the wrapper that called it which Does something useful we presume with the status headers and body and then returns that to the wrapper that called it And it returns it and it just passes it right back at the chain, right? It kind of looks like this Right, so if I so if I'm using these middlewares, and I've got this app that I'm running Okay, this app is the smart part. This is my logic Then I've got these middlewares that do things for me, right? I don't always want to have to specify like for example Okay, so the first one common logger, you know if you're running like a PHP app on Apache for example You've got Apache that's writing out these log files, right? So, you know nginx will do the same thing But sometimes you want to like get a log of just this stuff that actually hits your app and not like you know all the requests for Static files and stuff like that you want to get You want to see just the requests that are hitting your apps you insert common logger into the pipeline What does it do as the request comes in? It hits common logger And common logger actually doesn't do anything with it until until the response comes back out, okay? So then common logger. What does it do? It takes a look at the status. It takes a look at like the you know the time That you know the the user agent that was used, you know, and it makes it like an Apache style log, right? Same thing with like these other middlewares like I'm gonna talk about rack lock for example like it is it is super simple You've got an environment variable called rack dot multi threaded Ed or multi thread. I can't remember anyway All it does is it it's got a mutex, right? And it says You know, maybe my app is not safe for a multi-threaded environment Okay, so like have you ever thought about that? Well, if my if my app isn't safe for a multi-threaded environment Like I have to figure out some single point of execution, right where I can say stop the world you run Right and then you run and then you run and then you run, right? So that a mutex is or a lock is is perfect for that because I can just synchronize calls to my app And I can say okay, you know, it's your turn now. It's your turn now. It's your turn I'm not sure about the the Like last last thing I knew I like the rails library was thread safe But I booted up rails 3 and anyway rails through was using rack lock somebody else could probably address that Better than I can. So anyway, then there's like these content type content length middlewares Basically, what are these doing? So it the rack spec says when your request comes back out when your response comes back out It better have a content type and it better have a content length, right? That's just HTTP Spec stuff and so you say okay if I'm too lazy to put that in why don't you automatically determine it for me? And so it'll say okay if you don't have a rack, let's take a look at the code like it is so simple Here's rack content type right. It's doing exactly what I told you on the way in boom It stores your app it also this one also takes a default content type in case you forget to specify a content type in your HTTP headers, right? It's called So it immediately what does it do it just calls your app calls whatever app it's wrapping? Okay, that could be another piece of middleware that could be an app the thing is it doesn't care That's a beauty right? It's decoupled right? It doesn't care all it knows is whatever. I'm rapping whatever that app is Rack specs that it has a method called call and it takes one parameter, and that's the environment I'm just gonna call it. I'm gonna pass it. I know what I'm gonna get back status headers body. I get it back And in this case all I say is if there's not a content type already in the headers Set one and then pass it back up the chain Right, so you see a lot of middlewares that are very Simple like this, and then we're gonna see a lot that are a lot more complex to that are like wow I didn't realize you could do that much, you know with just a with just a An array of status headers and body, but you can do some amazing things How are we gonna run this thing it's easy to run a rack app, okay? This is this is like the verbose way to write it Okay, so if you want to run this app take this code stick it in a file called my app Rb whatever you want and just invoke it with the Ruby interpreter. What's it gonna do? Requires the rack library sets up an instance of rack builder rack builder just takes that chunk that's in the middle right there, right? And it just evals it instance evals it right so rack builder has three methods use map and run and It just takes it just takes it takes and it returns an app when you call this to app method Right it actually creates an instance of a rack URL map if you want to kind of dig down deeper And it's just it's a real simple way to build an app right then you just say Call my handler in this case. I'm using web rick, right? But the beautiful thing is is rack has already it's already abstracted that out for us Like we don't have to figure out how to pass this app to web rick or to fin or to mongrel or to passenger or to whoever Because that's what rack it does for us, right? We say run my app run it on port 9 2 9 2 you can stick a host in there if you want Rack ships with a tool called rack up. Okay, what is rack up rack up is just basically It's just basically what I told you it's like it it takes it creates an instance of the builder and Takes the code in your config.ru file Slurps it up sticks it inside a builder and off you go right so it's just a little bit more terse right so notice this When I go to this all I did was you know just move just remove some of the verbosity, right? So this I would stick it in a file called config.ru run it with rack up You rack up dash h will give you an option of or give you give you give you some options that you can use with Rack up you can run it in a different environment run it on a different port, etc Use a different server. I think it defaults to I think it defaults to web rick. Yeah, because obviously that's one that ships with Ruby Right, there's a cool little library called shotgun, right? So what happens when you when you fire up your app and it's running and it's in memory Right you tweak it right because something's broken or whatever you're developing you tweak it and then it's like crap I got a I got to go back to my console, right? I got to kill the process. I got to fire it up again. Then I got a refresh, right? It's kind of a pain Ryan Tomaco He's one of the github guys now. He wrote a wrote a nice little library called shotgun basically what it does is it It loads your app in a separate process every single time so you you So like every time every time your app gets hit every time it's requested it loads in a separate process So you don't have like your old application code. You understand what I'm saying not your head like this if you're still Okay, all right five people. I think Okay, the rest are just too lazy to nod. I know you guys are smarter than that. Okay Routing how do you how do you so? It's like I said so right so you can mount all kinds of different apps at all kinds of different places, right? I can mount an app on the route right so when somebody requests the route of my website some app runs And then when somebody requests slash Downloads or whatever a different app runs right a file server maybe and then when somebody Requests, you know my my my different post URLs or something different app runs How do we route? Sinatra DSL Is kind of the one that's often imitated never equaled people are always trying to imitate the Sinatra DSL If you haven't written a library that imitates the Sinatra DSL You're behind You need to get on it because like yours could be so much cooler than Sinatra, okay? rack mount Like I said, I'm gonna upload a lot of this stuff to These are just some basic examples of you know, here's what you do it. How here's how you run a Sinatra app Here's how you use the rack mount library I'm gonna upload this so I want you guys to download. I just have a few minutes left So I'm just trying to run rush through the end here All kinds of debugging libraries Take note of these rack lint and rack show exceptions. You've got a rack shell So imagine you're running your app boom you crack open a shell and You're you're like in your app so you can make requests and you can do all kinds of stuff right right from the shell You can see the responses coming back from your server. I mean it's awesome Let's see rack bug check that out if you do rails Make mental note of rack bug. It is awesome Forget the name of the guy Brian home camp is it that's right Brian Hill camp did that awesome library rack debug not ready for one nine yet I'm gonna skip Let's see Okay Middleware There's lots of middleware out there, please whenever you think like I'm gonna write Something to do this like don't do it. I promise you somebody already wrote it head over to github check it out Check out rack contrib check out check out the rack library There are a couple useful middlewares in the rack library. You can do streaming Chunked HTTP responses. You can do e-tag headers like automatically you can do You know sessions and cookie handling me you get all this stuff With rack you get all of it I actually have there's a sample app that I've got in the repository So when you when you go and you download the code from the repository, there's a little app there Just run it with the ruby interpreter. It's it's a it's a Twitter cash limiter app So basically it's just a very simple rack app. It just makes sure that you don't hit the Hit the Twitter API more than it likes to be hit, right? That's all it does But it's a it's a kind of a cool example of a raw rack app. It's complete with unit tests You can run the tests and everything so this is an app that you can just download you can say what is all this? Rack stuff about it's very simple I think it's like a hundred and something lines of code and you can check it out and you can run it and you can say Okay, I get rack now Since I'm done I just want to know you know are there any are there any questions anybody has about rack Yeah Yeah Right, so if so you're talking okay, so if I'm gonna so if I'm gonna use the use method You know what I'm talking about in the The in the rack builder DSL remember I showed that app What's got the rack builder and you can call three methods inside use map and run? When I say use this class right use rack Content length or in this case content type was the one that we showed I can say use rack content length comma And then whatever I pass after that right I can pass it a list of arguments that all just get passed to the constructor When it gets initialized does that answer the question? Yes so You know Honestly, I Somebody have an answer for that. I honestly I would I would either focus separate process or Use something like you know there are libraries specifically for that like delayed job and yeah, dude Right on it's all been done. I don't have to do anything. You just got a oh, thanks, dude. Thanks for your lab Okay, let me go. Let me just kind of let you know Here's where you can download the code Here's where you can find me. It's a pretty lame blog, but I don't know go there if you don't have anything to read I'm on Twitter. Thank you very much