Laravel 6 Advanced - e6 - Pipelines

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome so this is actually episode 6 of level 6 advanced so I just finished recording the episode but I figured if I did a quick intro I might help everybody know what we're actually going to be building and here it is so this may seem very simple at first but check this out using pipelines we've implemented an entire way to filter what if I only want it active imagine that these zeros and ones are active and inactive well we can add an active equals one and now check it out only active what if I say active equals zero then of course we get that what if we want it to sort this well we can add another one we'll say sort equals let's do it in ascending order and check this out now it's an alphabetical order but notice that active is still zero and on top of that we've actually got pagination so we've got different pages and as you notice of course everything remains the same so how cool is that so stick around and I'll show you how to build this from scratch cue intro welcome back so in this episode we're going to be talking about pipe lines now as a very quick aside a pipe line is actually a design pattern found in object-oriented programming now luckily for us level actually ships with an implementation of pipe line so we don't actually have to implement it from scratch we can simply just use it however I'm in the lair of documentation and if I type in pipeline or pipe lines truthfully nothing comes up and this is because pipe lines is one of those not really public facing things about level now as you get deeper and deeper in your learning of level you can leverage some of the things that level actually uses internally to your advantage in your application and pipelines is one of those things so up front let's take a couple of minutes to explore how pipelines are actually used in the level framework then let's do something very very cool with a real world example of filtering posts and this something that can be implemented in many different ways but a pipeline is a perfect example of how to actually do it so let's jump right to it I have a fresh installation here of laravel the only thing I've done is set up a database behind the scenes and I set up from posts for the example that we're gonna be working with today but I'll go through all of that when the time comes so let's start right off the bat what is a pipeline so a pipeline imagine is as if you were putting together pipes and each pipe could be a straight pipe maybe it could be a bent pipe at 90 degree in 45 elbow or maybe it could end and you can hook up a host to it so a pipeline imagine it as a real pipe so how does that translate into code well in code a lot of times you'll have steps so something comes in and we need to take the necessary steps to get it ready for its final destination that's what pipelines help you do so let's explore middleware we've talked about middleware and the channel before definitely check out the lesson on how to create middlewares we're more interested about how it actually works so if we go inside the apps directory inside the HTTP directory we have our middleware when your request comes in it runs through a series of tasks and it's either a pass or fail kind of situation it either throws an exception or it handles it in a particular way now these middleware here are actually registered in a kernel so to find the kernel this is the one we're looking for there are two kernels in level one is for console and one is for HTTP request we are talking about HTTP request so this is the kernel that you're looking at so here it is this right here is basically a pipeline so as your request comes in there's gonna be a certain number of steps that the request goes through we see here five of those now just as a quick aside what are some of these well for example it checks if the application is in maintenance mode and if it is let's actually check out what it does now when we go into this check for maintenance well there's nothing here however there is an actual check for me that is inside the vendor directory so when we take a look at this we get to the handle method every single step needs to have this handle method and the handle method will accept a request and next and next is just simply the next pipe so we are passing it the next pipe so when you're ready you say something like okay return the next pipe and you pass on the request so that's the way it works you'll accept a request and you'll accept the next step you'll do what you need to do in this particular step and when you're ready you either throw an exception or you go on to the next step until you get to the end and there's no more steps at that point so we see here that what it does is it throws a maintenance mode exception so it runs through the entire application and if it determines that the app is down for maintenance and we can actually dive into what this is but basically what it does is it actually adds a small hidden file in the application that tells laravel that the application is down for maintenance that's just the way it works a little bit outside of scope of this lesson but in here it actually goes in and you see tries to find this file in the storage path and if it does find it it's going to be inside framework and down then of course the application is in down mode if not then this notice that this is actually outside of this if statement so if the application is down for maintenance it'll perform this otherwise here it is we are just returning the next step in the request so where do you see pipeline well so far we haven't seen pipeline anywhere in this and the reason for that we need to dive a little bit deeper into how middleware actually applied now let's go back to the kernel class and we see that this kernel class actually extends HTTP kernel that is just an alias for illuminate foundation HTTP kernel let's jump into this class and this is the true implementation of the kernel class so now we take a look right off the bat right up here we see that we have this pipeline so there we go we finally actually see some pipeline action so let me actually skip ahead to send request through the router the way that it works is that the request comes in and then level tries to go ahead and run the entire request through every single registered middleware and then it actually dispatches to the router so we know we're actually going to be going so we see this here new pipeline so to the pipeline we pass the application and then we send the request through the pipes now it does do a quick check here because there is a skip middleware and if that's turned off then of course it's just going to be empty now notice that this is just an array so the through method accepts an array and the array is built up using this middleware or of course if it's skipped then it's just an empty array then we actually just go ahead and dispatch to the router so that's the way it works now we can keep going deeper and deeper into the foundation of letter ville but let's explore the example and I think that this will drive the point home let me close everything up and let me show you what I've set up for this example I have this test project here and these are just titles of posts and then a column of whether they are active or not so all I have done is there is a create post migration that just simply has a string of title and we have a small integer of active so I do have a post Factory and if we've pulled that up all I have is just a title with a fakir sentence of two words and then we have a random integer of zero or one it will just randomly generate an active or inactive post okay then I do have a post controller but it's not doing much right now it just fetches all of the posts and then it pulls open this post index view now this index view all that has is just a simple HTML table and then for each post we actually just have a row very very simple set up I didn't want to bore you with the setup for this but at the end of the day this is what we have is just a list so the first thing I want to do is I want to show you how I would do if we were not to use pipelines so here's the way it would work let's say that I want to filter between active and inactive posts so you may add a query string here and just say okay so I want everything where active equals one right now that doesn't do anything so let's make it work let's go back to the post controller and let's do all of our work here first of all I can't just fetch all of the posts I actually only need to fetch the ones if we have an actual active state so here's what we could do we could just grab a query and this will return a query builder for us so we can continue to chain things to it we could say okay if the request has a key of active in that case I know I need to do something to my query I would need to take my posts query and now we need to set a where statement and then we'll say okay we're active and we can set that equal to whatever was passed in from the request so if one was passed in this would be equal to one and then at the end I would need to actually fetch my posts from the database right so I need to call the get method on it I do need to save this because I do now have a collection so we'll save that to post and now if we hit refresh there we go we now have all posts that are equal to one now of course if I hit zero on this then we get zero and if I hit something that doesn't exist like two then of course we just get nothing all right fair enough but now let's take it to the next level what if I wanted to sort by title so maybe I would think of something like okay and I want to sort ascending okay but that of course doesn't work we'll have to repeat this bear with me let's do it one more time so we'll say sort and now we need to do an order by write all basic level stuff so we need to do an order by on the title column and we'll set it to whatever sort is okay does that work yep that works and of course we could say okay give me in descending order and we see we have V coming back up in alphabetical reverse order great but as you can tell this is probably going to break very very quickly so in comes pipeline let's go ahead and refactor this code to use pipeline instead we can use the underlined pipeline implementation that ships with level this is going to save us a ton of time so here's what I'm thinking let's create some filters for ourselves and of course a filter would basically be this is one filter this would be one filter so in my app let's go ahead and create a new directory and we'll call it query filters and then inside of query filters let's have a new PHP class and let's start with this very first one of active so I want the name of the class to match what I want to actually use in my query string so we'll say active and inside of this active one we'll start with just one but of course eventually we'll have a nice repeatable pattern that we can easily add a bunch of filters to and even reuse our filters so what do we need active to do well of course we need active to receive the query so how do we do that what is the method that needs to be inside active well if you remember you need to have a public function with the name of handle and this is what's going to be called through the pipeline so the handle method will accept the request next as you remember next is what we need to call when we are done with this particular filter now to keep it consistent with level let's go ahead and actually make sure that this is a closure and we can actually import this at the top if we want to like so that way is nice and clean so we want to make sure that next is a closure because at the end of this all we're going to have to do something like query take next and pass through the request that's how every single middleware ends and that's because of pipelines so we need to follow this same convention so eventually we have to do that so how do we actually handle that well we're going to just return next if well if it doesn't have the keyword active in the request so we can do a very similar check as we did here except that it's going to be first right we're not checking if it has the key we're checking if it doesn't have the key so if the request that is being passed in does not have a key of active in that case we need to go ahead and just move on to the next filter whatever that is however if we get to this line here it means that there is an active and what I mean by that again just a review is that we have a query string by the key of active we could do just a sort and not have active and that will sort everything but of course you see that we have zeros and ones so we don't know when active is present on the request and when active is not so that's why we need to check to make sure that we do in fact want to actually do any sort of filtering based upon active so with that in mind what do we need to do in here we're going to return some sort of well we need a builder so how do we get our builder into this active class as it turns out this right here is actually our builder because at this stage this is our builder so we are just simply returning our builder we can save this to a variable just to keep it nice and clean so we could say ok our builder is actually the next one so with our builder at this point how do we handle an active request well here it is we already wrote the code for that so we can just simply grab this code and bring it over to active alright so that is going to be working for us we need to hook all of this up and that's where the magic happens with pipelines so what we need to do is the following let's create a new variable up here and we'll say ok so here is my pipeline we can resolve that out of the container and we can request to get a pipeline now the pipeline that we're going to use is illuminate pipeline pipeline so we'll go ahead and grab that class just make sure that you import that at the top right again we're using illuminate pipeline pipeline so in my pipeline the way that it works is we're going to send our query right that's what we want to send through this pipeline I'm going to actually move this post query because that's what we want to send through this pipeline right we have this empty query that just fetches all these posts you want to run each of them through each of our query filters so once we have that query sent through the pipeline what are we gonna do well we need to run them through the following array of pipes and of course right now we just have the one so we'll say app query filters and then we'll grab active bus again we'll add these more as we have more filters so once we're done sending it through well what do we need well we just need to return whatever my query builder at the end of all this is that's what I need so we can actually call then return just go ahead and return whatever you have okay let's go ahead and die and dump just the pipeline just to stop the process so we can see what we actually have let's clean up our code let's go ahead and try to hit refresh and let's see what we get back the first thing is we get a call to undefined method pipeline through yeah I misspelled it let's fix that there we go all right and then we have that whoops another misspelled then return I'm sure you saw that there we go all right so we have a builder instance at this point so to actually see it why don't we actually perform the query so let's go ahead and do a get right at the end of this and let's see what we get we get a collection of 100 posts so that makes total sense because notice that active is not in the request let's go ahead and add active so say active equals let's grab all of my active posts and now we get 56 notice how we have 56 so that is actually working how cool is that all right so let's not get ahead of ourselves let's create another query filter and then we do a big round of refactoring to actually make this really really simple to do so let's save this active one and let's do another one for the sorting remember this was the other one that I had here is this sorting in descending order so let's do sort this stays the same except that we are looking for sort this time we'll get our builder and then what do we to do with our builder well we already have it down here so we'll go ahead and order by we'll bring that into this one and there we go so what's the next step well we need to add that to our pipelines so let's add this right here as sort and we can actually get rid of all of this all together and all we would really need is just this pipeline get now pipeline doesn't quite make sense here really this is my posts so let's rename that to posts and in that case I can actually get rid of this altogether and as a matter of fact I can actually inline this gets right here and we can get rid of that line and that's starting to look much much cleaner all right let's hit refresh there we go so the sending order ascending order how awesome is that how easy was it to implement this let's go to inactive only we can get rid of one or both and it still all works exactly the same so pretty cool all right let's start a round of refactoring to make this even cleaner I want to extract an abstract class that I can unload some of this logic because if you notice we already starting to have some repetition and I definitely don't want that so let's create an abstract class and we'll simply call it filter this is going to be the class that all of them will extend and let's start to unload some of this logic so the first thing I want to do is actually let me make this an abstract class there we go and now we can come back here and say ok so this extends filter and then let me copy that over to my active and so here we are so we know that we're going to have to check if this key exists every single time so wouldn't it make a little bit more sense if we move that up to the parent sure I think it does so let me grab my entire handle method from one of the filters and what I really want to do is I kind of want to just leave the handle method inside my abstract class and maybe just have an individual method maybe call the apply filters that actually handles the filtering part so that way whenever we regenerate one of these classes I wouldn't have to do something like parents handle right and cuz then I would have to pass in the request and then I would have to pass in next so that's still kind of dirty I don't want to have to do that let me undo that we'll come back and I think that this solution it's gonna be a little bit cleaner for us so yes we're gonna do this but then let's simply just delegate to a new method so we'll return this and again it's a method that doesn't exist we'll call it apply filter and so to apply filter we need to pass in a builder right that would make more sense so I can actually move this line back up here that way we could just have a filter and we don't have to worry about this next and request and all of that so let's go ahead and make sure that anybody who extends this class follows the contract we're going to be looking for a protected function called apply filter and we know that this is going to accept a builder but this of course needs to be abstract otherwise we're going to have to actually put a body and we're not interested in a body we just want every single class to handle this force so all right so now that we have this let's clean up this sort so we're not going to have a handle method anymore what we're going to have is a protective function of apply filter and this already has our query so all I need to do is this one line right here so I'll bring the return builder order by and I can get rid of all of this and here is my final sort filter how much cleaner is that so because we refactored some of this repetitive logic out of our actual filter or filter itself is very very clean let's do the same refactor in active so again we're going to need that apply filters function and all it needs is this because we're getting our builder already and I can get rid of all of this right here so right now in my filter I'm actually putting sort so we need a way to do this dynamically and again we have this active class and we have this sort class so we can actually use a level provided helper function that is called class based name let me show you what it actually does very quickly so right here my handle method I'm just gonna do a die and dump and I'm gonna show you what class base name will do for us so I'm just gonna pass in this at this stage I don't hit refresh here and notice that it says active so that's the very first class that we actually hit it has a capital A and furthermore imagine that the class actually had two names something like something else right what would you want this to actually be well something else should probably translate through something underscore else so we need that to be in snake case so let's actually extract this into its own method so let's figure out a way to get our key from the class name so let's create a new method of filter name alright so filter name let's go ahead and actually add this method and it'll be protected and filter name is going to return basically the same thing we had up there so we'll say give me we can use STR that's aluminum support STR and we do have a snake case right here and then again we're gonna use that class base name again and just pass in this because we are extending it will be sort and it will be active even though we're putting that in the parent class notice how when we actually tested it out it didn't say filter but it said active so now here we have filter name and of course down here we can actually refactor this to use that exact same thing as well so we'll go ahead and perform that refactor right here then over in the active class we could do it right here and then of course we can actually replace active as well all right let's head back to the browser hit refresh yep everything is still working all right so that's working let's try sorting as well we'll sort in descending order whoops we must have made a mistake here ah yes of course so this actually needs to be just replacing the key so we still need to look in our request for the filter name all right so there we go we could do ascending yep that's all working awesome so that's it would basically have this query filtering working right where we need it let's do just one more quick round refactor and that is that right now this is kind of cluttering my post controller this is really a model thing so why don't we actually refactor to use maybe a name constructor so we could say posts equals posts and let's maybe call it all posts it's gonna be a named constructor I'll grab all of this and let's cut it out completely let me go to my post model and in my post model let's create a new public static function called all posts and in here I'm simply going to return this right here now I did have to import pipeline up here at the top but there we go so we have a nice working implementation using pipeline so let's do one more filter just to finish everything up and let's see how easy it is now that we have our final filtering so let's do one for limit what if I only want a max count of maybe ten posts let me create a new filter here we'll call it max count and again capital M and C will turn that into the snake case that we need so that's gonna work automatically for us so we'll say the name is max count so in here we'll simply take as many as we have in our request so that's it now we just need to register that as one of our filters and so it'll say max count and let's go ahead and add that in now we'll say max underscore counts equals maybe just subscribe ten and there we go so we get ten now if we want ten inactive ones now we get ten inactive ones same thing with descending it all works how awesome is that you may be wondering well is this like pagination and it's definitely not like pagination if you wanted to do pagination we can tag that on top of all of this a pagination would still work check this out so if you know anything about pagination you know that of course of getting something you will actually have to paginate the results and let's just keep it at five just for the sake of this example when we hit refresh now we have five posts so one small caveat about this is the following let me go back to my index method let me actually go ahead and output out the links so we'll say posts links so we can actually move between pages and so when I go to page two notice what happens to all of my query filters I'm gonna hit page two whoops they're all gone so that's not exactly what we want because if we did that now we have active posts so we need a way of just telling level to not erase whatever query filters I already have I simply just want you to paginate and it's a bit of a trick but the way that it works is that we need to grab and actually append everything except the actual input so we can use the append method and in here we can simply say okay so grab all of my request inputs and then go ahead and fetch my links let me hit refresh and notice down here when I hover over to notice that the address has everything that we need so there we go so now we have pagination and filtering all working thanks to pipelines so pipelines just makes this easy and so clean and again if we needed another filter you saw how easy it was to add yet another filter all we need to do is just create a class and go ahead and add it and because we have access to the actual query builder right in here we can perform any sort of stuff right from the Builder so this is what's gonna allow us to actually have really advanced filtering built in but again it's all driven by pipeline so pipeline again is a very very useful object oriented design pattern and a great implementation that ships right with laravel that we can tap into and use to our advantage in our applications so that's going to complete our lesson today as always don't forget to subscribe and thanks for watching
Info
Channel: Coder's Tape
Views: 42,208
Rating: undefined out of 5
Keywords: laravel 6, laravel 6 tutorial, laravel preview, laravel 6 what's new, laravel, laravel service container, laravel ioc container, service container, service container laravel, container laravel, laravel container, laravel ioc service container, laravel advanced, laravel filters tutorial, laravel pipe dream, laravel pipeline, laravel filter products, laravel query builder tutorial, laravel query string route, laravel table filter, laravel advanced project
Id: 7XqEJO-wt7s
Channel Id: undefined
Length: 28min 53sec (1733 seconds)
Published: Sat Sep 07 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.