‫Another nice small feature
‫that we can add to an API is
‫to provide an alias route to a request
‫that might be very popular,
‫so it might be requested all the time.
‫And, for example, we might want
‫to provide a route specifically
‫for the five best cheap tours.
‫So, if we'd use our regular route here
‫with the filters and with all the features
‫that we already have,
‫the request would look a little bit like this.
‫So, let's get ride of all of this.
‫So, the five best and cheapest tours.
‫So, that means we have a limit of five
‫and then we're gonna sort by ratings and by price.
‫So, sort and then the average rating,
‫and descending, so minus ratings average.
‫And, in case they have the same average,
‫then we want the cheapest price possible.
‫And so, we're gonna sort also by price.
‫Let's quickly take a look at the results.
‫And, indeed, we get five tours here.
‫And, Postman does this scrolling again.
‫So, we have tours with 4.9,
‫4.9, 4.9 again,
‫4.8, and 4.7.
‫And so, these are actually our five best and cheapest tours.
‫If we said cheapest and best, well,
‫then maybe we would have to sort by price first
‫because some of them are not really cheap.
‫For example, this one.
‫But, we selected, first, the average.
‫And so, we sorted by the highest average first
‫and, only then in case of a tie, basically,
‫only then, by the price.
‫Now, let's say that this is a request
‫that is done all the time and we want
‫to provide a route that is simple
‫and easy to memorize for the user.
‫So, let's go to our app and try to implement that.
‫And, we're gonna start at their routes, so tour router.
‫And, we then need to create a new route.
‫And, let's do that here, right at the top.
‫So, router.route.
‫And so, how are we gonna call this route?
‫Well, let's say top-5-cheap.
‫So, quite a simple name, but it's gonna work.
‫And then, we actually only want
‫to get requests to this route.
‫And so, now it's time to think.
‫How are we gonna implement this functionality?
‫Well, in essence, what we want is
‫to actually still get all the tours just like here.
‫And so, let me go ahead and start by copying
‫and pasting that here.
‫So, we really still want to use this function here
‫because it doesn't really make sense
‫to rewrite all of the logic that is in there.
‫But, before we can call this route ender,
‫we basically want to prefill some of the fields
‫in the query string.
‫So, we already know
‫that our query string should look like this.
‫And, actually we can add some more stuff here.
‫But, in essence, our query string
‫has to look something like this.
‫And so, the solution is gonna be to run a middleware
‫before we actually run this getAllTours handler.
‫And so, that middleware function is then
‫gonna manipulate the query object that's coming in.
‫And so, this is yet another really nice example
‫of using middleware because you really need
‫to get familiar and used to this concept
‫of using middleware strategically in order
‫to change the request object as we need it.
‫So, let's add it here then.
‫So, tourController.
‫And then, the middleware function
‫that we're gonna create in a second,
‫which is gonna be called aliasTopTours.
‫So, let's copy that name, move to the tourController
‫and I'm gonna put it here at the very top.
‫So, exports.,
‫then request,
‫response,
‫and what's the third argument
‫that we need in the middleware, remember?
‫And, I know the Express section is kind of far away already
‫at this point, but I hope you remember
‫that the third argument here needs to be next.
‫So, in order to call the next middleware
‫that's in the middleware stack.
‫Give it a save.
‫And so, this error there should disappear.
‫And so, let's do what we said we would do.
‫So, basically to manipulate the query object
‫so that when it reaches the getAllTours handler,
‫it's then already different.
‫So, let's first do that and then really
‫take a look at what happens.
‫So, remember, the limit is gonna be set to five.
‫And, remember that everything is strings here
‫and so I'm setting this also to a string.
‫Now, what else did we had?
‫So, we have this sort, so let's just copy this here
‫and say req.query.sort.
‫It should be this.
‫And then, we can actually also specify some fields
‫so that the user doesn't get all of the fields
‫that we have in there.
‫So, let's say that we only want the name, the price,
‫the ratings average, the summary,
‫and the difficulty.
‫Give it a save and now all we need is next,
‫otherwise this middleware will be stuck here forever
‫and cannot move on.
‫So, let's now figure out a bit better
‫what's actually gonna happen here.
‫So, as soon as someone hits the top-5-cheap route,
‫we will start.
‫The first middleware that's gonna be run is aliasTopTours.
‫So, the function that we just created.
‫So, what this is gonna do is
‫that it will set these properties of the query object
‫to these values that we specified here.
‫Basically prefilling parts of the query object
‫before we then reach the getAllTours handler.
‫And so, as soon as we then get to this function,
‫the query object is already prefilled,
‫even if the user didn't put any
‫of these parameters in the query string.
‫And so, in essence,
‫what we're doing here is prefilling the query string
‫for the user so that the user doesn't have
‫to do it on his own.
‫And so, let's now actually go ahead and try this.
‫So, I'm copying this.
‫And, here it's not tours.
‫It is top-5-tours.
‫Whoa, what's going on here?
‫For some reason, it doesn't find this route,
‫so let's go back.
‫So, top-5-tours.
‫And so, here in the route, ah, okay.
‫It's called top-5-cheap,
‫so my mistake here.
‫So, cheap, send it now,
‫and that's still not correct.
‫Ah, yeah.
‫Of course, I still have to put the tours here, of course.
‫So, we are in the tours resource
‫and the whole router is mounted
‫onto this tours route, remember that.
‫And so, it's in that tours,
‫that kind of mini application, remember that,
‫where I created this top-5-cheap route.
‫So, let's hope it works now.
‫And, indeed, it does.
‫So, that worked, that's fantastic.
‫Now, of course, we could do a lot more alias routes here,
‫but that's not really necessary.
‫I really just wanted to show you the concept,
‫show you that it can be a nice feature
‫to add to any API and also I wanted to, again,
‫show you the power of middlewares.
‫So, we're talking about Mongoose here,
‫but still, it's very important to keep getting familiar
‫with the Express concepts that we talked about before.
‫Anyway, we're now done with our API features.
‫In the next video, we're just gonna quickly refactor all
‫of this to make the entire code a bit more modular
‫and, of course, better.