Rack ‘em, Stack ‘em Web Apps

Video in TIB AV-Portal: Rack ‘em, Stack ‘em Web Apps

Formal Metadata

Rack ‘em, Stack ‘em Web Apps
Title of Series
Part Number
Number of Parts
CC Attribution - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this license.
Release Date

Content Metadata

Subject Area
While Rails is the most common Ruby web framework, it’s not the only option. Rack is a simple, elegant HTTP library, ideal for microservices and high performance applications. In this talk, you’ll see Rack from top to bottom. Starting from the simplest app, we’ll grow our code into a RESTful HTTP API. We’ll test our code, write reusable middleware, and dig through what Rack provides out of the box. Throughout, we’ll balance when Rack is a good fit, and when larger tools are needed. If you’ve heard of Rack but wondered where it fits in the Ruby web stack, here’s your chance!
Slide rule Web service Presentation of a group Link (knot theory) Robotics Coma Berenices Cartesian coordinate system Disk read-and-write head Mereology Ruby on Rails Library (computing) Neuroinformatik
Axiom of choice Complex (psychology) Server (computing) Game controller Code Connectivity (graph theory) Web browser Mereology Web 2.0 Web service Array data structure Internetworking Software framework Interface (computing) Gender Interactive television Fitness function Staff (military) Cartesian coordinate system System call Degree (graph theory) Web application Computer animation Logic Website Quicksort Communications protocol Abstraction
Slide rule Server (computing) Computer file Code Client (computing) Parameter (computer programming) Web browser Mereology Bookmark (World Wide Web) Number Expected value Revision control Web 2.0 String (computer science) Energy level Social class Dependent and independent variables Email Content (media) Bit Instance (computer science) Cartesian coordinate system System call Type theory Radical (chemistry) Web application Hash function Enumerated type Personal digital assistant Object (grammar) Communications protocol
Type theory Radical (chemistry) Mapping Personal digital assistant Set (mathematics) Flag Software testing Web browser Quicksort Mereology Address space Physical system
Mobile app Code Direction (geometry) Open set Parameter (computer programming) Expected value Root Software testing Social class World Wide Web Consortium Dependent and independent variables Email Inheritance (object-oriented programming) Validity (statistics) Key (cryptography) Content (media) Unit testing Instance (computer science) Cartesian coordinate system Computer animation Personal digital assistant Configuration space Object (grammar) Cycle (graph theory) Quicksort Middleware
Domain name World Wide Web Consortium Information Code Source code Letterpress printing 1 (number) Bit Web browser Cartesian coordinate system Web 2.0 Type theory Message passing Process (computing) Personal digital assistant Different (Kate Ryan album) output Fundamental theorem of algebra Computer architecture
Web 2.0 Single-precision floating-point format Interactive television Statement (computer science) Software framework Bit Online help Quicksort Cartesian coordinate system Routing Abstraction
Mobile app Existential quantification Mass Number Latent heat String (computer science) Single-precision floating-point format Software testing Social class Dependent and independent variables Scaling (geometry) Mapping Information Cellular automaton Bit Instance (computer science) Cartesian coordinate system System call Flow separation Uniform resource locator Hash function Personal digital assistant Statement (computer science) Configuration space Object (grammar) Quicksort
Slide rule Code Multiplication sign Robot Motion capture Online help Parameter (computer programming) Function (mathematics) 2 (number) Robotics String (computer science) Software framework Data structure Error message Social class Area Dependent and independent variables Matching (graph theory) Information Data storage device Bit Database Representational state transfer Regulärer Ausdruck <Textverarbeitung> Cartesian coordinate system Ruby on Rails Type theory Personal digital assistant Quicksort Object (grammar) Routing
Point (geometry) Beta function Code Branch (computer science) Parameter (computer programming) Client (computing) Mereology Web 2.0 String (computer science) Gastropod shell Software framework Form (programming) Email Dependent and independent variables Matching (graph theory) Moment (mathematics) Content (media) Bit Database Line (geometry) System call Radical (chemistry) Web application Uniform resource locator Message passing Process (computing) Query language Video game Cycle (graph theory) Row (database)
Point (geometry) Dataflow Dynamical system Building Computer file Link (knot theory) State of matter Code Multiplication sign Control flow Parameter (computer programming) Web browser Mereology Wave packet String (computer science) Social class Dependent and independent variables Email Information File format Closed set Content (media) Bit Type theory Pattern language Right angle Quicksort Object (grammar) Writing Row (database)
Installation art Dependent and independent variables Computer animation Connectivity (graph theory) Statement (computer science) Pattern language Software framework Cartesian coordinate system Sequence Middleware Form (programming)
Server (computing) Dependent and independent variables Mobile app Email Game controller Key (cryptography) Validity (statistics) Multiplication sign Line (geometry) Cartesian coordinate system System call Web 2.0 Mathematics Integrated development environment Chain Configuration space Diagram Quicksort Object (grammar) Middleware Form (programming)
Authentication Point (geometry) Web page Mobile app Server (computing) Computer file File format Code Software developer Real number Source code Fitness function Online help Cartesian coordinate system Number Fluid statics Message passing Chain Pattern language Quicksort HTTP cookie Middleware Form (programming) Exception handling
Arithmetic mean Game controller View (database) Touch typing Plastikkarte Software framework Cartesian coordinate system System call
Dependent and independent variables Digital electronics Validity (statistics) Insertion loss Cartesian coordinate system Stack (abstract data type) System call Computer animation String (computer science) Energy level Configuration space Middleware Routing
Building Dependent and independent variables Token ring Surface Multiplication sign Cartesian coordinate system Mereology Cuboid Video game Software framework Cycle (graph theory) Freeware Middleware
the and here and welcome everyone I thank you for coming this afternoon I hope you had a good 1st aerials count so far and my name is Jason Clarke I work for new relic previously on the region now I'm working with some other teams on some back and services today I'm here to talk to you about rack rack is a library that you may have heard a little bit about but but before we begin about it I've got a couple of links for you but the first one is the slides for this presentation so if it's easier for you to fall along on your computer you want to references that Winkel take you there and then the 2nd link is just a fun little rock application that I built I to demonstrate a few the principles that are going on here it lets you post textbase robots little fight each other it's were probably not going to get down to demoing at but if you're like me and you can a drift a little here and there during a presentation feel free to go head fight . robot likes . com enough this Conf we have a go to conduct keep it clean keep a professional but go have fun with that if it like so let's get down to the to what we're here to talk about today so if you go around in Ruby on Rails you've probably heard rack mentioned before but what is that it's a it's a little ambiguous until you begin where this fits in the ecosystem what part of place
12 the easy answer is that rack is a gem like so many other things in Ruby I This is a gender provides a minimal modular adaptable interface for developing web applications the FIL like me that doesn't really tell you a whole lot but I we can draw a picture the kind of demonstrates what rack is about where it fits in our staff so when a user comes to a website from a browser they make a request that request goes across the internet and gets handled by some sort of web server typically something like unicorn or whom the that web server then has to figure out what to do with that request and that is where rap comes into play rack is the interface that those web service talk to to communicate the web request just happen rack then in turn is able to turn around and pass that request along generally to all web framework of your choice something like rails or Sinatra so wreck is sort of the blue that sits between your web server and your application now this is really cool because this is the principle by which you can swap out your web servers without changing your application code you can change who met a unicorn back and forth you could even run on web brick and all that is fine because everybody talks through this common interface of rack
but rack is also available for you to use directly there's no reason you can't leverage when it provides to write your own code against it instead of relying on a framework to take care of that for you now why would you wanna do a crazy thing like that I mean I'm here rails complement telling you how you can do things other than use rails but there's a couple of places where I feel like knowledge of rack uh really plays in and it's a good fit the 1st is when you need the absolute most speed out of your Ruby code because the web server is making 1 method call interact hand you a web request just happen there's nothing else in between there's no logic there's no abstractions there's no nothing happening to take time so if you have something you need it to be as fast as possible for review to be handling it getting down to the rack clear takes everything else out of the way the 2nd reason and I put forward its simplicity and I got put an asterisk on this this is a certain sort of simplicity it makes something simpler the protocol for how you communicate interact as we'll see in a few minutes is really based it's method calls arrays hashes things that you're very familiar with but you're trading that for other sorts of complexity that then you have to handle yourself so it's a trade off you might make some things more simple might make other things a little harder and we'll talk about where that's true the other piece that's nice about rack is like I alluded to there's a high degree of reuse to some of these components because rack is such a standard part of the Ruby web ecosystem things that are written to work with 1 RAC based applications can often work with another application were often with 4 applications a written against entirely different frame so that's a nice part that you might be able to use code that you right if you're writing interact that if he wrote it as a before filter in your controller you wouldn't be able to share it easily alright so that a lotta yammering
about what rack years let's take a look at some code and this is 1 of my favorite snippets of Ruby um actually it's pretty much in the world
is best this is a fully functioning rack web applications now that you put this initially in a configured . are you file don't let the dot argue that full at all that still just a Ruby file stands for rack up the we define a class called application in that class we defined 1 method the entirety of wracked protocol is a single method this method is called called and it takes 1 parameter called in uh it's a passion will look closer at what what's in that national that on the response side racks expectation of a call method is that it will return back an array that has 3 parts the 1st value in an array is the status code the HTTP status code to return back and so in this case we're saying 200 everything's all good the 2nd parameter in this array is a hash of HTTP headers that will be fed back to the client browser now I left this in the in this case more often you have something like the content type at least some basic values you would set and I might excluded those 2 in a lot of these slides just to you know keep the amount of text on but in the HTTP header that you need to communicate back to the client you just put in that and then the last thing in this three-part array is 80 and array of the content that wanting this and that and this is slightly different than you might expect you might think 0 i do just 1 hand a string back right my HTML or my text that I'm sending back across the wire the Jason on both rack expects that this the content object in the last place is something that will respond to each and so the array is the easiest way to accomplish that to have give it you know a thing that it will be able to enumerate across and then it takes whatever it gets out of that enumeration and that's what it sends down the wire to clients the so that's it that's the protocol for how the web server communicates to wrap the request this coming in and then gets the response back from that rack application now can figure out are you you gotta get the thing started and so there is a run method the rack makes available at that level and you hand it an instance of a rock application of an instance that response to this call method and now when we go to our terminal we can say rack up that is a executable that's installed by the rack genome and it will spit out a little bit of front matter here tell us about some versions tell what port number it's running on and now it's ready to receive requests we can get a request to it in the simplest possible way just by going to a
browser going to local host 90 to 92 and it tells us that this is good enough I there are other ways of accessing this tho and I I like to play with them because some of the later cases it will look at are a little easier with some of the other tools and 1 of them is curl so curl is a command line tools readily available across most Unix-based systems in you can in the most basic setting say curl and then the same address you would have typed into your browser and it will spit back onto your terminal terminal the text that it received and there's all sorts of flags were only gonna look at a couple of them that this will come in useful a little later when we look at things that aren't as easy to just type into a browser the so were were Ruby
it's a big part of ruby culture is testing as so we have a map here already let's see what it would take to get some tests wrapped around them and fortunately as you might expect the Ruby community provides through gem called rack test you include this
and here downfall just like any other genome you would require rack test then make that available in that the holes in the classes that you can use in these examples I'm going to be showing many test because that's kind of my flavor for things this all works perfectly well with our spec and super well supported across the so and it may test would look something like this so we have our application test drives from any test test the 1st thing we do is we include direct test method so what this does is it makes available a whole bunch of helpers and that you can then have access to throughout the rest of your test class you can actually do things like open up the many test base class and do this for everything if you know that you're using it everywhere where do it on a point-by-point basis like we're doing here 1 expectation that rack has has of your test class tho is that it will provide a method called half and that that method will return an instance of eurac applications so this allows us to control what we're actually testing the methods and helpers that rack test provides will interact with this app method to figure things out and as we'll see later but this is this plays nicely because you can also do things like middleware instantiation or configure this however you want to in returning a valid rack application that you want to test the test a pretty basic but it gives you a methods where you can invoke all the typical HTTP verbs you would expect so in our case we just wanted to get what was at the root so we just get slack once that's executed it were running in Star Wreck out and rack test will put the responses from that what happened when I got back into an object called last response will look a little closer what this response object is later but we can interrogate it for things like was a successful status code what was the content that was it was her headers so you can see how you can get into a nice unit testing cycle here of being able to have the various things in the Urals make requests against a out and then see what it's going to respond back to you in alright so that's
all well and good so that's I'm sure somebody would pay you tons of money to make the Web out the just returns a static string but but most of us will need to have some sort of more dynamic interactive thing going on and that in the parameter that we looked at is the key
to uh to all of the dynamic behavior that you're going to put into your application everything that you need to know about the incoming web request is in that in as I mentioned it's a Hashim must take a look at a
little bit of what's in there there's a lot of values and you know you can have a print these out do whatever to be able to to dig deeper but some of the important ones that you should know about are that includes the HTTP request method so in our case this is a get so as we refer to that you know when you type something in your browser and just hit go that's the method that's going to get sent there it gives us a lot of different half information so we can know what not requested and where and then also wraps up any input this coming in so with again that there's no real input the gets sent along you just requesting the URL but as will see in a few minutes there are ways that I with they post message or some of the other HTTP methods that you're expected actually send data along with the request and that's available here in the end so this is a modification to our basic apt to start digging into the and then do something a little more sophisticated although not that sophisticated yet what we do is we look at that path info that was provided there and that gives us through the relative path after the domain of what the user has requested and in this case we look to see if it matches exactly slash bot and if it does were returning a 4 0 3 which is the HTTP status code for forbidden and we give them a nice little message to let them know that we spotted them trying to get somewhere that they're not supposed to very very sophisticated source code here this process of taking a look that 0 at the URL that's being passed on and turning that into what code you're going to execute is actually a really fundamental piece of Web architecture In fact it's called
routing and this is 1 of the things that you get out of every single web framework in fact some of them via their claim to fame is how easy they make routing or how about conventional they can do those sorts of things this is really a place where
you feel the lack of frameworks if you just try to go at your own interact you will end up building your own abstractions to keep from having deeply nested if statements which are most of what you're gonna see here so I'm gonna get to debate you can imagine if you had even 10 rout your in application they can get a little bit tough to manage without some help ran does provide
you a little bit of assistance that so you're not entirely trapped in a land of nested case statements to get some sort of routing and it does it through a method called mass so in our configure you we originally showed that we just called run on an application that's the only thing that requests were going to be able to come into will wreck will also support you providing at the leading prefix of the URL and then send those calls to specific AP objects so here we've made under the rack compatible application object called status and this will I receive calls the come to a slash status you were on the app rather than than going to the main application on it so you can imagine that in a modest scale if you had a small number of of droughts that you were trying to deal with you can very nicely partition those off into their own separate application classes which is also kind of nice for testing in a single responsibility and rock will let you do some basic routing to get the request supposed to go to those that i where they belong if you got more than 1 or 2 of them there is also a URL map class where you can essentially handed a hash of the strings for the prefixes and the instances that you want and add enough depending on how many of them you have and how you're using it it can be a little tidier than the MAP method calls in you can figure you the so the in
the the hash it has all the information we could possibly want in it if the hash like munging around hashes knowing that he's you know you can botch the key value and it looks like something's not there in hand and things don't exist it's kind of messy and so rack helps us cell with that with a class called rock request wrecked
request you hand it in in this coming and then it provides a lot of hope a method to give you cleaner access to the things that are expected to be inside of this wrecked request so in this case we use are replaced are look up in that impact for path info in upper case with an ice method called path info instead now this if we botched the typing on it and said Pat info it's going to give us a no method error rather than just returning a single value and behaving in kind of a mysterious way so I highly recommend using rack request any time that you're doing more than 1 hour 2 very basic accesses of things that are in the that really a type these things up so looking a little further at this but it's still a little bit more sophisticated thing so if you rather than having slashed bought return us just a static strain but let's make it a little bit more like a real show wrapped where you can save bot slash and IDE that you're interested in and it will still the light you but at least it'll tell you let us thing here you were trying to get at now this is a little ugly like I said routing is 1 of those areas where frameworks help is actually a journey and must remain both genomes that are independent gems that Ruby on Rails and Sinatra used for doing routing so you know you could mixes in yourself the in this case we're using a regular expression to match against the the rout the running at the per cent Aura erm here with the curly braces is really nice when you're doing it rejects that wants to match forward slashes of because forward slashes and you don't have to like backslash forward slash to get them as literals into it and then we have parentheses around that a backslash D. plus and that grabs as a capture the idea that we passed in and the dollar 1 on the lower lying below it pulls out the value that was matched when that rejects there there are lots of ways that this could be cleaner entire this is the most concise way defended on slides so don't take this as best practice but is kind of a luster to the where you could go with person appear Urals and taking out the information that you want so is there an easier way like I said this is where you really with frameworks I mean Sinatra's you're DSL for anybody who's used a where you just get and then give it the strain you can put parameters and it just with colons on the names like they do so much to help you out here so this is a place that you might wanna look for that help if we wanted to
transform this into a little bit more of a real application the once we've done that match so rather than just returning it about a string value we can do whatever sort of code we want inside that so here I we have some mythical database class the goes and looks up by idea the things that we have in store it returns back that bought and as an object and then we just 2 s that in our outputs you can imagine as this database was storing things as Jason structures that that this would be the way that you could have just sort of a typical RESTful API talking back and forth like there's no deep learning you don't need anything here apart from the database class to be able to look at the data that you want a return back so as we've seen before Pearl comes in handy for doing this and if we curl at bought slash 1 look up in a database there we have a funky little Lasky robot with the ID 1 on it as the response to the this is an
HTTP GET like we had mentioned so it's not expected to have any parameters really except for the URL of the query string has provided there it can send headers but we're not reading any of those but we wanna make this a little bit more full-featured like we have a a database that were reading out of we wanna let people right into it and for that the HTTP method that you should use is post post allows us to send data along with
so will adapt our call method a little further and don't worry this is the most that this method is going to grow and you can see where the pain points are here in the routing we're talking about we had our match that we've seen before so as long as were in the bar and now we have a branching here In this branch says if the request is a get get method which is provided for us by that rack request and then we would do this stuff that we're already doing before of looking it up but if the post it it's if the request is opposed then what we need to do is we go to that request and we read the body that comes in so this is the data that the client is sending to us in a lot of web applications this would be something that would be East coming from a web form that somebody had entered but it could also be from an API Client calling it directly or as we'll see in a moment there's easy ways to make pearl post data to a URL rather than just get from receiving a post like we said we would like this to write into our database so having match the idea and having read the content and we can do whatever we need to with that and return a response to the client indicating that we were successful in saving the record that they sent to us so this is like the basic shell of a restful but API here in 10 lines of code you know excluding the database or whatever you bring into to do that pretty straightforward and the things that you that you get from your frameworks make this a little cleaner and make this tight here but these are all the moving parts that are really necessary to get this job done taking a look at how this works at at the terminal if you say curl with a minus capital X then you can provide an HTTP methods other than GET which is what it will default to we give it the full neural with the idea of the thing wanting in the minus minus beta then allows you to assume the data along the you want to actually post it gives us back a message that we wrote and if we then turn back around and you would get against that same neural we receive back at the data that we had sent so we have the full life cycle of posting and reading Ch
unsurprisingly given that rack has a request class also has a response class which helps you in building up the valid responses don't
it's it's pretty useful and then it fills a couple gaps in that format I mean for 1 you know it's it's pretty strict for you do need to make exactly those 3 elements and make sure that the contents the way that it's supposed to and it also rec response also allows you to kind of have a little bit more of a flow and how you're building things up rather than making that array right at the point when you need to return it gives you an object to sort of tally up the information into you and then at the time that your finished ask it to write it out the wire the so we interact with Braque response by instantiating a new 1 it doesn't take any parameters to start that necessarily and then we can set various things on this response it's sort of a stateful builder type of pattern so 1 of them is right you can write to it and that were right to the body of and you can do that as many times as you want you can continue to append things you can imagine that you were doing this with an HTML based thing you know maybe you read something from header file and write that in the you write some other piece of dynamic content and then you write a fluttery and enough progressively build up that response how you want to and then when you're done you call response not finish and it generates a valid wrapped response to be handed back across the wire if we pride in at that point and took a look at the response finish but what it returns back to us like like we've experienced before is that 3 array a status code headers and then the body but to even look a little different and this is part of why you want to use records what's 1 of them is in its append the content link based on the things that we wrote in now web browsers will act OK things don't break dramatically if you don't provide this but it is an HTTP specs and it is better for you to provide that information if you wanna make sure that you're compatible with all callers additionally that content that last thing that we have been passing as an array with strings in it rack is wrapped up in and objects object in this object actually takes care of some more complicated scenarios in when things are nested in a certain closing behaviors the the response training but then it will take care for you so you don't need to know about those things if you use direct response so at this point we have a
valid act and it returns data and we can interact with the make a request a responses but there's another major component of how the RAP works and that is middleware and this is 1 of the most powerful patterns of this brings to play and 1 of the things that applies the most when you're in other frameworks
so back American Fig . are you where we had our run statement for application you can use a method that's provided there called use and install a middleware and installing the middle where they get installed in the sequence it gets called so we could have done multiple installations there instead use this middleware then use this 1 then use this 1 and what that forms that forms at a
cold chain that's going to get flowed through so the 1st request that comes from the web server will hit the 1st middleware that you said use in the configure you then hit the next 1 then hit the next 1 and eventually most of the time that stand here happened in the response goes back up through the chain those middlewares I take
something shaped like that so they have to have an initial lines initialize expected to take an app that is the next thing in the chain the middleware's gonna call you have to say about a way so that you can make a call against later so in this form this middleware doesn't actually do anything useful all it does is like takes request hands of all the you can do your own work before and after that call on the and you can manage the environment you can deal with the response and change what's there you can't control what's going in and out so here's an example of a very basic sort of the a API key validation as middleware we instantiate a request for object to read at we get the uh HE GPX API key header which is a pretty standard value for passing an API key along and if the key matches some predetermined string that we've chosen I chose B then I will go ahead and let the call through they knew the key everything's fine if they don't then we will immediately returned from this middleware that request will never make it to the application object itself to be handled so in diagram
form we can then we get to the middle ware in the middle ware says I responsible for this returns and nobody else further down the chain get to read a chance to get involved with that so middleware a very powerful tool allowing you to apply the sorts of crosscutting concerns whether it's logging or authentication some things we're all of your in points across any portion of your app need to have the same behavior fit very well and rails actually is built on a ton of middleware this is a huge pattern that's applied there for a lot of crosscutting concerns so if we look at this I once we've installed or authentication we can grow against that will get our forbidden message if we look at the status code it would tell us for of 3 the if we crawl with a minus h minus capital H we can give it headers in the HTTP format that they expect the Keenan colon and then the value and once we pass a ballot API key their requests than is allowed to go through so wrapped
itself comes with a number of middleware Citroen uh that you can use and there are lots of them around I 1 of them is wracked static so if you need to serve static files out of Iraq application allows treaties to declaratively set that up and it has some basic session support both with backing source on your server and with cookies that you can solve this actually often get used with Sinatra if you want to have sessions because it's the middle where the can get installed I'm has debugging help things that will show you here's a nice exception page when you're and development things that you code reloading it you can optionally installed and a lot of the niceties that you have and reals are available as middlewares with rack itself and that brings us to the last of that which is to
talk about we're rack intersects with all the other framework so we mentioned earlier on that you know rails and smart and all these things are built on top of the but what does that really mean mean
for rails your Rails application is Air Act that there is something in rails there has a call method that takes in and when those requests command that's getting dispatched to your controllers and your routing your views and all those other things but all that is downstream of a call method that you don't have to write because rails does it for you that's not the only place where rails touches rack 0 and you can actually embed
rack applications into the routing inside of a Rails application so here in our routs followed by using the mount command you can hand at Arak happenstance and then give it the URL where it should delegate to that rack and any request circuits there will get sent onto that rack application similarly rails allows for using middleware there's a use method so in your application configured in his user user middleware just like you did in are configured are you have but also provide sees insert before insert after so if you have some concern about the sequencing of your middlewares you can control that from in there now you can't do that from rack itself and so how Israel's accomplishing this well it turns out the rails actually has its own internal middleware stack and so when you configure use those in in the rails level is actually going into that middleware stack you can install middleware set the configure you at the rack level just like you would but you won't see those when you do things like Raykar middlewares and ask rails to show you all the things that has installed so that's a fun little tripping point if you're ever looking around for how things are plugged in Sinatra as well just like Rails is just a rack out at the end of the day when you call Sinatra based in you
driver thing from that but it's just a rock application and in fact although you almost always use helpers and call render a hand back strings into all the nice things it's natural let you do you can always fall back to handing back a valid rack response and Sinatra knows what to do with it just handed on back because it is just a wreck but so that's a
quick tour through rack and where it fits we've looked at how you would build a basic application with the moving parts are there there in the box we looked at the request and response life cycle and what plays into that we've looked at middleware and how you can use those 2 kind of compose an act together and layer things in iraq applications we've looked at how this plugs into the various frameworks now a really just touched on the surface of this and having given a lot of really concrete details on but I did a course for Pluralsight so if this is something that is of interest to you I am I actually have a bunch of tokens that people can get a free month's worth of a of time on or open up Pluralsight and you know that screencast fills in a lot more detail that goes into a lot more of what's in the box with reckon a much more realistic example a building adjacent based API with so hopefully you've all found this useful and I can't see how much time we have where there's any time for questions right thank you very there so the
use of each